Search code examples
c#xnacamerarotationframe-rate

Moving the camera in the direction it is facing


I've followed a tutorial on how to make a first person camera rotate and move in a 3D world in XNA on the Microsoft website. But when I rotate the camera along it's Y axis, it doesn't move the direction it is rotated/facing, instead it moves as if it was facing the direction it was originally faced.

Here's my code:

static Vector3 avatarPosition = new Vector3(0, 0, 0);
static Vector3 cameraPosition = avatarPosition;
Vector3 cameraReference = new Vector3(10, 0, 0);
// Create a vector pointing the direction the camera is facing.
Matrix world = Matrix.CreateWorld(new Vector3(0, -1, 0), Vector3.Forward, Vector3.Up);
Matrix rotationMatrix = Matrix.CreateRotationY(MathHelper.ToRadians(0));
int Rot = 0;
Vector3 worldVector = new Vector3(5,-2, 0);
Matrix view, proj;
Vector3 cameraLookat;
Update()
{
    world = Matrix.CreateWorld(worldVector, Vector3.Forward, Vector3.Up);
    if (IsKeyDown(Keys.W))
        avatarPosition += new Vector3(0.2f, 0f, 0);
    if (IsKeyDown(Keys.S))
        avatarPosition += new Vector3(-0.2f, 0f, 0);
    if (IsKeyDown(Keys.A))
        avatarPosition += new Vector3(0f, 0f, -0.2f);
    if (IsKeyDown(Keys.D))
        avatarPosition += new Vector3(0f, 0f, 0.2f);

    if (IsKeyDown(Keys.Left))
        Rot += 1;
    if (IsKeyDown(Keys.Right))
        Rot += -1;

    rotationMatrix = Matrix.CreateRotationY(MathHelper.ToRadians(Rot));
    // Create a vector pointing the direction the camera is facing.
    Vector3 transformedReference = Vector3.Transform(cameraReference, rotationMatrix);
    // Calculate the position the camera is looking at.
    cameraLookat = transformedReference + cameraPosition;
    // Set up the view matrix and projection matrix.
    view = Matrix.CreateLookAt(cameraPosition, cameraLookat, new Vector3(0.0f, 1.0f, 0.0f));

    proj = Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(45), graphics.GraphicsDevice.Viewport.AspectRatio,
                                          0.1f, 1000);
    cameraPosition = avatarPosition;
 }

Can someone please tell me why the camera does not travel the way it is rotated? Or can someone please just give me the damn code to make one?


Solution

  • I appears the problem you are experiencing is coming from this area of the code:

    if (IsKeyDown(Keys.W))
        avatarPosition += new Vector3(0.2f, 0f, 0);
    if (IsKeyDown(Keys.S))
        avatarPosition += new Vector3(-0.2f, 0f, 0);
    if (IsKeyDown(Keys.A))
        avatarPosition += new Vector3(0f, 0f, -0.2f);
    if (IsKeyDown(Keys.D))
        avatarPosition += new Vector3(0f, 0f, 0.2f);
    

    Instead of translating the avatarPosition directly along the x or z axis, it should be using the direction you're pointing which appears to be your transformedReference variable.

    For instance, to move forward the way the camera is facing:

    if (IsKeyDown(Keys.W))
        avatarPosition += transformedReference;
    

    However, since the transformedReference variable appears to be normalized, it may not move the avatar the distance you'd hoped. In that case simply multiply it by some constant MOVEMENT_SPEED for something like such:

    if (IsKeyDown(Keys.W))
        avatarPosition += transformedReference * MOVEMENT_SPEED;