• Advertisement
Sign in to follow this  

Vsync makes character walk weirdly (Bullet Physics)

This topic is 905 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

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 this post


Link to post
Share on other sites
Advertisement

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.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement