Aligning Player Movement with Camera

In a game with a static camera (looking down at the level) it is important to align the character movement with the camera. Failing to do so creates a distorted input feeling as the input and the actions of the player character don’t correspond to each other. To achieve a correct movement, the directions have to projected from the screen onto the scene.

Wrong movement along axis of the coordinate system.
Wrong movement along axis of the coordinate system.

Naive implementations of player movement use the axis of the coordinate system as directions. Left and Right correspond to the [1,0,0] direction and Up and Down to the[0,0,1] direction. This implementation is correct and usable as long as the camera is correctly aligned to this axis. If the camera is not aligned the movement directions no longer correspond to the perceived directions of the player (see image above). To correct this we have to extract the directions from the camera.

Corrected movement
Corrected movement along projected directions.

To compute our new directions we unproject three points from camera space to world space. Most framework/engine have built in functions to do this ( godot, opengl, unity ). We have to preform 3 unprojections for the points: (0,0), (1,0) and (0,1). By substracting the result of latter two from the former we obtain two 3D-Vectors that represent our new directions. To receive planar movement direction set the height value (mostly y) to zero and normalize the vectors.

Godot:

 var p0 = cam.project_position(Vector2(0,0))
 var pH = cam.project_position(Vector2(10,0))
 var pV = cam.project_position(Vector2(0,10))

 camH = pH - p0
 camV = pV - p0
 camH.y = 0
 camV.y = 0
 camH = camH.normalized()
 camV = camV.normalized()

camH is the horizontal movement direction and camV the vertical. Instead of using the axis of the coordinate system ([1,0,0] and [0,0,1]) as movement directions, use camH for left/right movement and camV for up/down movement.