# How do I create a 3rd person camera?

I currently have a camera class set up and have my model/player loaded but I can't get my camera in the correct position by changing the x,y,z coordinates.

I have set up my "game" with a separate class for the model/player and a class for the camera. I am fairly new to XNA and most of what I have already got is from a tutorial from my lecturer.

Here is my player/model class:

public class Player
{
public Model model;
public Matrix world = Matrix.Identity;
public Vector3 position;
public Vector3 direction;
public Quaternion rotation = Quaternion.Identity;
public BoundingSphere collision;
public float speed = 2f;
public float moveForwards;
public float moveLeft;
public float forward;
Matrix[] transform;

public Player(Model m, Vector3 iPos)
{
model = m;
position = iPos;
direction = new Vector3(0, 0, 1);
transform = new Matrix[m.Bones.Count];
m.CopyAbsoluteBoneTransformsTo(transform);

foreach (ModelMesh mesh in m.Meshes)
{
collision = BoundingSphere.CreateMerged(collision, mesh.BoundingSphere);
}
}

public Player()
{

}

public BoundingSphere getSphere()
{
return collision.Transform(world);
}

{
moveForwards = (player.ThumbSticks.Left.Y / 5);
moveLeft = (player.ThumbSticks.Left.X / 32) * -1;
}

public void update()
{
rotation *= Quaternion.CreateFromAxisAngle(new Vector3(0, 0, -1), moveLeft) * Quaternion.CreateFromAxisAngle(new Vector3(1, 0, 0), moveForwards);

Vector3 motion = Vector3.Transform(direction, rotation);
position += motion * forward;
world = Matrix.CreateFromQuaternion(rotation) * Matrix.CreateTranslation(position);
}

public void Draw(Matrix projection, Matrix view)
{
Matrix[] transforms = new Matrix[model.Bones.Count];
model.CopyAbsoluteBoneTransformsTo(transforms);

foreach (ModelMesh mesh in model.Meshes)
{
foreach (BasicEffect effect in mesh.Effects)
{
effect.EnableDefaultLighting();
effect.Projection = projection;
effect.View = view;
effect.World = transforms[mesh.ParentBone.Index] * world;
}
mesh.Draw();
}
}
}


And here is my camera class:

 public class Camera
{
Vector3 position;
Vector3 newposition;
Quaternion cameraRotation;
Vector3 targetOffset = new Vector3(0, 1f, -6f);

public Matrix view = Matrix.Identity;
public Matrix projection = Matrix.Identity;

public Camera(Game game, Vector3 xPostion)
{
position = xPostion;

projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, game.GraphicsDevice.Viewport.AspectRatio, 1.0f, 1000000f);
}

public void update(Matrix targetWorld)
{
Quaternion rotation;
Vector3 target;
Vector3 scale;

targetWorld.Decompose(out scale, out rotation, out target);
cameraRotation = Quaternion.Lerp(cameraRotation, rotation, 0.15f);
newposition = Vector3.Transform(targetOffset, targetWorld);
position = Vector3.SmoothStep(position, newposition, 0.8f);

Vector3 cameraup = Vector3.Transform(new Vector3(0, 1, 0), Matrix.CreateFromQuaternion(cameraRotation));
view = Matrix.CreateLookAt(position, target, cameraup);
}
}


Could someone help me get my camera in the correct position?

When doing a 3rd person camera, simply think about the point in 3d space that the camera is located and the point in 3d space that it is looking at. Set those two points and build a view matrix from them.

//I want to locate my camera 25 units behind the player and 5 units above him
Vector3 cameraPosition = targetWorld.Translation + (targetWorld.Backwards * 25) + (targerrWorld.Up * 5);

//I want my cameras to look at a point 10 units directly in front of my player
Vector3 cameraTarget = targetWorld.Translation + (targetWorld.Forward * 10);

//build a view matrix that represents this
view = Matrix.CreateLookAt(cameraPosition, cameraTarget, Vector3.Up);


Run this code each frame as targetWorld changes and the camera will follow along obediently.

• Hi, thanks for the answer. So does that code go into the camera class? Also do I need to remove any code that I have or just add that in? Mar 26, 2013 at 12:03

I have managed to get the camera into a 3rd person position by changing the camera offset values but the camera is not at the right hight. When I fix this I will post the fix for that also.

Here is the camera class as it stands:

namespace Camera
{
public class Camera
{
Vector3 position;
Vector3 newposition;
Quaternion cameraRotation = Quaternion.Identity;
Vector3 targetOffset = new Vector3(0, 175f, -100f);

public Matrix view = Matrix.Identity;
public Matrix projection = Matrix.Identity;

public Camera(Game game, Vector3 xPostion)
{
position = xPostion;

projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, game.GraphicsDevice.Viewport.AspectRatio, 1.0f, 1000000f);
}

public void update(Matrix targetWorld)
{
Quaternion rotation;
Vector3 target;
Vector3 scale;

targetWorld.Decompose(out scale, out rotation, out target);
cameraRotation = Quaternion.Lerp(cameraRotation, rotation, 0.15f);
newposition = Vector3.Transform(targetOffset, targetWorld);
position = Vector3.SmoothStep(position, newposition, 0.8f);

Vector3 cameraup = Vector3.Transform(new Vector3(0, 1, 0), Matrix.CreateFromQuaternion(cameraRotation));
view = Matrix.CreateLookAt(position, target, cameraup);
}
}
}


Thanks to Steve H we have managed to get it working.

Here is the camera class with the correct height as well as placement behind my model.

class Camera
{
public Matrix view = Matrix.Identity;
public Matrix projection = Matrix.Identity;
public Matrix world = Matrix.Identity;
public BoundingSphere collision;

public Camera(Game game)
{
projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, game.GraphicsDevice.Viewport.AspectRatio, 1.0f, 1000000f);

}

public BoundingSphere getSphere()
{
return collision.Transform(world);
}

public void update(Matrix targetWorld)
{
Vector3 position = targetWorld.Translation + (targetWorld.Forward * 110) + (Vector3.Up * 100);

Vector3 target = targetWorld.Translation + (targetWorld.Backward * 10) + (Vector3.Up * 80);

view = Matrix.CreateLookAt(position, target, Vector3.Up);
}
}