# Vsync makes character walk weirdly (Bullet Physics)

## Recommended Posts

I've made a character controller for Bullet from scratch. It's kinda simple, but works fine, except for when Vsync is on. I can't post the entire code because it would take about 200 lines, but it works like this:

• It is a normal btRigidBody, NOT kinematic.
• Gravity pulls it down like any btRigidBody
• Movement is made by btRigidBody::setLinearVelocity

This is the "core" function (it's not very organized, but does the trick):

void ThirdPersonCharacter::ProcessInputInternal(XMFLOAT2& Move, XMFLOAT2& Look, bool Jump, bool Sprint)
{
XMFLOAT3 Focus;
XMStoreFloat3(&Focus, CharacterCamera.FocusPosition);
CharacterCamera.SetCamera(Focus, CameraDistance, CharacterCamera.Rotation + XMFLOAT3(Look.y, Look.x, 0.0f));

if (CharacterBody->getLinearVelocity().getY() <= 0)
{
CharacterState = OnGround ? Resting : Falling;
}

btScalar Friction(0), Damping(0);

if (OnGround)
{
State LastCharacterState = CharacterState;
btVector3 Velocity(0, 0, 0);

Friction = 1000;
Damping = LastCharacterState == Jumping ? 0 : 1;

if (CharacterState != Jumping)
CharacterState = Resting;

if ((Move != XMFLOAT2(0, 0)) && (LastCharacterState != Jumping))
{
Friction = 1.0f;
Damping = 0.0f;
Velocity = btVector3(Move.x, 0, Move.y).rotate(btVector3(0, 1, 0), CharacterCamera.Rotation.y).normalize()
* (Sprint ? 5 : 2.5);
MeshRotation = CharacterCamera.Rotation.y;
CharacterState = Walking;
}

if (Jump)
{
Friction = 1.0f;
Damping = 0.0f;
Velocity.setY(Velocity.getY() + 5);
CharacterState = Jumping;
}

if (Velocity != btVector3(0, 0, 0))
CharacterBody->setLinearVelocity(Velocity);
}

CharacterBody->setFriction(Friction);
CharacterBody->setDamping(Damping, 0);
}

[hr]
When Vsync is off everything seems to be fine. But when it's on, the problem varies (or doesn't happens) based on a single line of code. When...

DynamicsWorld.stepSimulation(FrameTime, 10);

Walking velocity is normal at the start, then it gets slower and slower until it stops and goes back to normal (and it goes on over again...)

[hr]
When...

DynamicsWorld.stepSimulation(FrameTime, 0);

It works perfectly fine, but I don't know if it's safe to do this. The docs say it disables the fixed timestep and uses the actual timestep, but I think that would be bad if the framerate drops (some objects could pass through others). Am I wrong?

[hr]
When...

DynamicsWorld.stepSimulation(1.f / 60.f);

This would not be a good thing, but I tried it only for testing purposes. It seems that whenever timeStep is equal to fixedTimeStep my character doesn't move at all (doesn't walk nor fall)

[hr]

I'm very confused. These changes only seem to affect the character itself. Can someone help me? Please ask for more details if you need more. I can upload a video if you think it would help.

##### Share on other sites

Solved it. The problem was that I was calling a SetPosition function inside void ThirdPersonCharacter::CharacterMotionState::setWorldTransform(const btTransform& WorldTransform) which updated the graphics position, but also called SetWorldTransform. So I just split that function in two and used the graphics update version.

## Create an account

Register a new account

• ### Forum Statistics

• Total Topics
628360
• Total Posts
2982262

• 10
• 9
• 13
• 24
• 11