# Move camera on X and Z only

How would you implement movement on a camera in order to always move it on X and Z coordinates, and if the camera has pitch yaw or roll it still moves only in those coordinates and doesn't fly up?

• How are you moving the camera now, and why can't you, at the end of every frame, just hammer the camera's Y coord? Aug 26, 2011 at 16:46

Anytime you applied a positional change (translation) to the camera, you would flatten that vector out.

Let's say in a non-restricted situation, where the camera could move along the Y-axis, that you have a movement vector like this:

Vector3 appliedMovement = new Vector(3, 7, 2);
cameraPosition += appliedMovement;


Just remove the Y component.

Vector3 appliedMovement = new Vector(3, 7, 2);
appliedMovement.Y = 0.0f;
cameraPosition += appliedMovement;


I would recommend making your mutator for your camera class do this, or make a helper function.

If you have a class for your camera, I would use a mutator:

public Vector3 CameraPosition
{
get { return value; }
set
{
if ( isUsingRestrictedVerticalMovement )
{
value.Y = 0.0f;
}

cameraPosition += value;
}
}
private Vector3 cameraPosition;


If you don't have a class for your camera, I would write a static utility method to call anytime you moved your camera:

public static class VectorUtils
{
static public Vector3 FlattenVectorHorizontally( Vector3 vector )
{
vector.Y = 0.0f;
return vector;
}
}


Using this helper function with our original code:

Vector3 appliedMovement = VectorUtils.FlattenVectorHorizontally(new Vector(3, 7, 2));
cameraPosition += appliedMovement;


You can make your helper function more efficient by passing by reference

static public void FlattenVectorHorizontally( ref Vector3 vector )
{
vector.Y = 0.0f;
}


If you use the version above that passes by reference, you'll need to call the method differently

Vector3 appliedMovement = new Vector(3, 7, 2);
VectorUtils.FlattenVectorHorizontally(appliedMovement);
cameraPosition += appliedMovement;


Note that this is exactly what Tetrad's comment in your original question was referring to.

In a first person camera, you can move the camera forward by adding the camera.direction values, scaled by speed * delta values, to the camera position. This moves the camera forward in the direction that the camera is facing. To move the camera forward on just the X and Z planes, you add camera.direction.x and camera.direction.z to the position. Create a new vector with camera.x, 0f, and camera.z, then normalize it, then scale it by speed*delta.

To move the camera left or right, you add/subtract the cross product of your vector with camera.up scaled by the speed*delta in the same fashion.

Here's the code using libgdx:

public void update(float delta) {
Vector3 xz = new Vector3(camera.direction.x, 0, camera.direction.z).nor();
if (keys.containsKey(FORWARD)) {
xz.scl(delta * velocity);
}
if (keys.containsKey(BACKWARD)) {
xz.scl(delta * velocity);
camera.position.sub(xz);
}
if (keys.containsKey(STRAFE_RIGHT)) {
xz.crs(camera.up).nor().scl(delta * velocity);