Creating and moving a third person camera

Started by
4 comments, last by ChristianFrantz 10 years, 10 months ago

I have a player class and camera class. I want my model to move and the camera to follow it. Simple enough, but when I move my model it decides to fly off the screen and then stops somewhere far in the distance, and then moves up and down on the Y axis. I'm not exactly sure where I went wrong with this one. The camera also doesn't move either, but that's not as much of an issue right now.


class Player
    {
        Model playerModel;
        public Matrix playerWorld;
        Matrix[] playerTransforms;

        public float speed = 2f;
        public float rotationRate = 0.3f;

        public Vector3 Position { get; set; }
        public float RotationX { get; set; }
        public float RotationY { get; set; }
        public float Scale { get; set; }

        public Player()
        {
            playerWorld = Matrix.CreateScale(.1f);
            this.Position = new Vector3(0, 1f, 0);
        }

        public void LoadContent(ContentManager content)
        {
            playerModel = content.Load<Model>("p1_wedge");
            playerTransforms = new Matrix[playerModel.Bones.Count];
            playerModel.CopyAbsoluteBoneTransformsTo(playerTransforms);
        }

        public void Update(float dt)
        {
            KeyboardState kbs = Keyboard.GetState();

            if (kbs.IsKeyDown(Keys.W))
            {
                playerWorld += Matrix.CreateTranslation(Vector3.Forward * speed  * dt);
            }

            if (kbs.IsKeyDown(Keys.S))
            {
                playerWorld += Matrix.CreateTranslation(playerWorld.Backward * speed * dt);
            }

            if (kbs.IsKeyDown(Keys.A))
            {
                Vector3 temp = playerWorld.Translation;
                playerWorld.Translation = Vector3.Zero;
                playerWorld += Matrix.CreateRotationY(rotationRate * dt);
                playerWorld.Translation = temp;
            }

            if (kbs.IsKeyDown(Keys.D))
            {
                Vector3 temp = playerWorld.Translation;
                playerWorld.Translation = Vector3.Zero;
                playerWorld += Matrix.CreateRotationY(-rotationRate * dt);
                playerWorld.Translation = temp;
            }
        }

        public void Render(ThirdPersonCam cam)
        {
            foreach (ModelMesh mesh in playerModel.Meshes)
            {
                foreach (BasicEffect effect in mesh.Effects)
                {
                    effect.View = cam.view;
                    effect.Projection = cam.proj;
                    effect.World = playerTransforms[mesh.ParentBone.Index] * playerWorld;
                }
                mesh.Draw();
            }
        }
    }

That's the player class. The error lies within the draw or update method, but I'm not sure what I'm looking for. When I press "w" it seems like the model moves behind me at first.


public class ThirdPersonCam
    {
        public Matrix view;
        public Matrix proj;

        public ThirdPersonCam()
        {
            proj = Matrix.CreatePerspectiveFieldOfView(0.78f, 1.7777f, 1f, 10000f);
        }

        public void CameraUpdate(Matrix objectToFollow)
        {
            Vector3 camPosition = objectToFollow.Translation + (objectToFollow.Backward * 10f) + (objectToFollow.Up * 15f) + (objectToFollow.Left * 1f);
            Vector3 camTarget = objectToFollow.Translation;

            view = Matrix.CreateLookAt(camPosition, camTarget, Vector3.Up);
        }

There's the camera class. This doesn't work either, as I have called the CameraUpdate method in my main game class and the camera doesn't move at all. The camera is following the player.playerWorld matrix when I call it.

If you see a post from me, you can safely assume its C# and XNA :)

Advertisement

Hey,

The code only makes some vague sense in that I can see what you're trying to do but it doesn't work like that. Unless the Vector3 and Matrix classes you're using has some implementation unknown to me.(which is completely possible!).

You appear to be adding matrices together? I would guess you meant to concatenate them (ie. multiply?)

Rather than try to concatenate in this way, create your position as a vector separately from the orientation then combine them together at the end by multiplying the translation matrix (created from your position vector) and your rotation matrix. Your object should maintain the position vector and orientation (in whichever format you choose to represent it) as member variables.

I am not sure what your Forward/Backward/Left properties are, it looks like they're vectors extracted from your matrix.This wont work if the matrix you're extracting them from is the concatenated matrix we see in your Player.Update method. However it should be fine if you use the rotation as I mention above.

A couple of things to think about after you have the basic camera working:

With your current implementation, you will have a *very* rigid camera and you will want to add some kind of 'tightness' control.

You will want to have some kind of adjustment for the target point on the object being looked at, looking directly at the object will make it difficult to see where you are going.

n!

[edit] The forum lost half my original post, but I think I remembered the bits that disappeared.

One way to fix your issue is that you can set the position and orientation of the camera to the object you want it to follow with an offset. on how far away you want it be from the player.

Alrighty so I figured out the problem. I actually had two cameras going at once somehow. So now I'm only using my 3rd person cam. The rotation with a and d work fine, when you can get the model in view...This usually involves some guess work and moving back and forth with w and s. My values for the camera have also changed.

I'm still having a hard time actually finding the model and chasing it. I've been messing around with the values a bit but nothing seems to work right


Vector3 camPosition = objectToFollow.Translation + (objectToFollow.Backward * 3) + (objectToFollow.Up * 3);
Vector3 camTarget = objectToFollow.Translation;

view = Matrix.CreateLookAt(camPosition, camTarget, Vector3.Up);

If you see a post from me, you can safely assume its C# and XNA :)

Why is your up vector always the same. I mean if you camera orientation is based on the player then you camera up vector will depend on your look vector.

When I get to coding the camera with the mouse, I'll end up changing the vector. I want a camera like WoW or guild wars. But for now, what I have works

If you see a post from me, you can safely assume its C# and XNA :)

This topic is closed to new replies.

Advertisement