If you’re using the CharacterBody3D default template, you probably have lines like these somewhere in your script:
var input_dir = Input.get_vector("move_left", "move_right", "move_forward", "move_back")
var direction = (transform.basis * Vector3(input_dir.x, 0, input_dir.y)).normalized()
Let’s say the player is pressing forward (W or up arrow on the keyboard), and nothing else. Then input_dir
becomes the vector (0, -1).
We then take that vector and turn it into a 3D vector with a y coordinate of 0, that is, we turn it into (0, 0, -1). Godot defaults to using the negative Z axis as its forward direction, so this is a vector that points forward in global space.
However, we don’t want the character to always move along the global Z axis when the player is trying to move forwards. Our character should be able to rotate, and then “forwards” should mean “move in the direction the character is pointing”.
To accomplish this, we take our global space vector, which was (0, 0, -1), and multiply it with the characters transform.basis
, which is a matrix describing how the character is rotated and scaled. Don’t worry too much about the math here - think of it as taking that (0, 0, -1) vector, and transforming it so it points along the characters -Z axis, instead of the global -Z axis.
Ok, so what’s happening with your camera, then? I don’t know exactly how you’ve set it up, but my guess would be that your camera pivot is a child node of your character, and that this child node is what actually gets rotated when you rotate your camera. This means that the CharacterBody3D
doesn’t get rotated, but always points the same way, and therefore always moves the same direction in global space, no matter where the camera is pointing.
There are two ways of fixing this:
- use the camera pivot’s
transform.basis
to determine the movement direction:
var direction = (pivot.transform.basis * Vector3(input_dir.x, 0, input_dir.y)).normalized()
- Change your camera logic, so that the actual
CharacterBody3D
node gets rotated, instead of a child node.