Brendan Keesing   

FOMOGRAPHY     Projects     Blog     About


Character Controller: Smooth Movement

February 14, 2021

You want your character to move forward. Easy right? Get the input, multiply it by the speed and call it a day:

1
velocity = joystick.y * movementSpeed * deltaTime;

HSV

Seems cool, but if you let go of the joystick, the character will come to an immediate stop. This is jarring. We want the character to have some sort of momentum, so they speed up and slow down smoothly. With this, we’re going to need to use forces:

1
2
Vector3 force = Vector3.forward * joystick.y * acceleration * deltaTime;
velocity += force * deltaTime;

This looks fine, but we also need to limit the character’s max speed:

1
2
if (velocity.magnitude > maxSpeed)
	velocity = velocity.normalized * maxSpeed;

HSV

Better. But how long does it take to reach the max speed? We can calculate this with:

1
timeToReachMaxSpeed = acceleration / maxSpeed;

What if we have two max speeds? One for walking and one for sprinting. This means that the time to reach the max speed will change depending on the max speed. I guess that makes sense for something like a car, but for a creature, that doesn’t feel great. We want more control over it.

The solution is to move the velocity toward a target velocity:

1
2
3
4
float sprintAmount; // 0 to 1 value, where 0 is walking, 1 is sprinting
float targetSpeed = Lerp(walkSpeed, sprintSpeed, sprintAmount);
Vector3 targetVelocity = Vector3.forward * joystick.y * targetSpeed;
velocity = Vector3.MoveToward(velocity, targetVelocity, deltaTime / timeToReachMaxSpeed);

HSV

Understanding this will give you silky smooth movement while giving you full control over the max speeds and velocity changes.



Twitter YouTube GitHub Email RSS