NewProger
NewProger

Reputation: 3075

Change movement according to camera direction

Good day. I'm working on a fps game, and I have a problem with camera, or with movement to be pricese... as it doesn't take camera position into accound when performs movement... I tried to fix it in several different ways, but I guess I just don't understand the math needed :(

Anyway, here's the code:

    static public void UpdateCharacterPositionAndCamera(float time)
    {
        //mouse look update
        float rotationSpeed = 3f;
        if (Input.mouseState != Input.mouseStatePrevious)
        {
            float xDifference = Input.mouseState.X - Display.gd.Viewport.Width / 2;
            float yDifference = Input.mouseState.Y - Display.gd.Viewport.Height / 2;
            yRotation -= rotationSpeed * xDifference * time;
            xRotation -= rotationSpeed * yDifference * time;
            Mouse.SetPosition(Display.gd.Viewport.Width / 2, Display.gd.Viewport.Height / 2);
        }

        //camera
        Vector3 cameraPosition = playerPos;
        Vector3 cameraReference = new Vector3(0f, 0f, -1f);
        Matrix rotationMatrix = Matrix.CreateRotationY(MathHelper.ToRadians(yRotation)) * Matrix.CreateRotationX(MathHelper.ToRadians(xRotation));
        Vector3 transformedReference = Vector3.Transform(cameraReference, rotationMatrix);
        Vector3 cameraLookat = cameraPosition + transformedReference;
        viewMatrix = Matrix.CreateLookAt(cameraPosition, cameraLookat, new Vector3(0.0f, 1.0f, 0.0f));
        projectionMatrix = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, Display.gd.Viewport.AspectRatio, 0.1f, 2500.0f);

        //movement
        float moveSpeed = 5.0f;
        Vector3 moveVector = new Vector3(0, 0, 0);
        if (Input.keyState.IsKeyDown(Keys.Up) || Input.keyState.IsKeyDown(Keys.W))
            moveVector += new Vector3(0, 0, -1);
        if (Input.keyState.IsKeyDown(Keys.Down) || Input.keyState.IsKeyDown(Keys.S))
            moveVector += new Vector3(0, 0, 1);
        if (Input.keyState.IsKeyDown(Keys.Right) || Input.keyState.IsKeyDown(Keys.D))
            moveVector += new Vector3(1, 0, 0);
        if (Input.keyState.IsKeyDown(Keys.Left) || Input.keyState.IsKeyDown(Keys.A))
            moveVector += new Vector3(-1, 0, 0);
        if (Input.keyState.IsKeyDown(Keys.Q))
            moveVector += new Vector3(0, 1, 0);
        if (Input.keyState.IsKeyDown(Keys.Z))
            moveVector += new Vector3(0, -1, 0);
        playerPos += moveVector * moveSpeed;
    }

Can you tell me how to change the move vector so it takes camera direction into account...?

Upvotes: 1

Views: 471

Answers (2)

Steve H
Steve H

Reputation: 5519

aere's how I usually do it:

   //movement 
    Matrix camWorld = Matrix.Invert(view);

    Vector3 moveVector = Vector3.Zero;
    ...
    if(...keys.Up... or ...keys.W...)
       moveVector += camWorld.Forward;
    if(... keys.right  or ... keys.D...)
       moveVector += camWorld.Right;
    ...
    moveVector.Normalize();
    PlayerPos += moveVector * moveSpeed;

Upvotes: 0

John Dvorak
John Dvorak

Reputation: 27287

Multiply the move vector by the camera rotation matrix, or its inverse (I think it's the inverse). It's the same as the view matrix, but without the translation. If you want to fix the camera onto a plane, you need to zero out the respective component afterwards and perhaps normalize the new vector. I'm not familiar with the XNA API, so I cannot tell you exactly which methods to use. You might be able to extract the rotation matrix from the view matrix, or you might need to look at the difference (lookAt-positios) from the origin.

Upvotes: 1

Related Questions