Character Movement in a Video Game

This article describes the basics of how to move a character where the character can separately apply forward impulse versus look around.

Typically, you'll have:


Quaternion lookOrientation;
Vector3 position;
Vector3 velocity;
float impulse;

You'll implement movement controls something like this:


onLeftTurn() {
  lookOrientation *= Quaternion( Up, TurnAngle );
}

onRightTurn() {
  lookOrientation *= Quaternion( Up, -TurnAngle );
}

onForwardMovement() {
  impulse = MovementImpulse;
}

You'll implement the player movement (stepping/update) like this:


onPlayerUpdate() {
  velocity += lookOrientation.frontVector() * impulse;
  velocity *= (1 - Friction);
  position += velocity * TimeStepSize;
  impulse *= (1 - ImpulseDiedown)
}

Initially, I'd try for a Friction of 0.04 and an ImpulseDiedown of 0.1, if your timestep is about one frame (i e, in the range of 0.012-0.017 seconds). The magnitude of MovementImpulse, TurnAngle, and the units for position/velocity depend on your world coordinate system.

In this system, you'll keep moving in the direction you were moving even if you look aside. However, as you start pressing move-forward when you look to the side, you'll start moving in that direction.

If you want the player to start moving in a new direction when they turn, even when they're not pressing forward, you can remove velocity components that are orthogonal to the forward vector. Add this as the second line of the update function:


  velocity -= (lookOrientation.rightVector() / velocity) * CorrectionAmount * lookOrientation.rightVector();

I'm assuming "/" between vectors is dot product. CorrectionAmount varies depending on how snappy adjustment you want; its value usually should be similar to that of the Friction coefficient, or slightly higher.