XNA Game Engine Tutorial Series #7 – First Person Camera
Note: Finish Chapter 6.5 before starting this chapter if you started the tutorial series before 12/10/2008
This one is quick because I’ve been very busy leading up to christmas, so here goes. This tutorial is on building a first person camera, the type used in most games these days. It can be moved and rotated. Later on we’ll learn how to apply physics to the camera so it can interact with the environment.
using Microsoft.Xna.Framework;
using System;
namespace Innovation
{
// A simple first person camera. Accepts rotation and translation
public class FPSCamera : Camera
{
// Keeps track of the rotation and translation that have been
// added via RotateTranslate()
Vector3 rotation;
Vector3 translation;
public FPSCamera(GameScreen Parent) : base(Parent) { }
public FPSCamera() : base() { }
// This adds to rotation and translation to change the camera view
public void RotateTranslate(Vector3 Rotation, Vector3 Translation)
{
translation += Translation;
rotation += Rotation;
}
public override void Update()
{
// Update the rotation matrix using the rotation vector
Rotation = MathUtil.Vector3ToMatrix(rotation);
// Update the position in the direction of rotation
translation = Vector3.Transform(translation, Rotation);
Position += translation;
// Reset translation
translation = Vector3.Zero;
// Calculate the new target
Target = Vector3.Add(Position, Rotation.Forward);
// Have the base Camera update all the matrices, etc.
base.Update();
}
}
}
Here’s how it would be used in a game. You will need to do a few things first though. First make sure the camera you are making is of type FPSCamera in the LoadContent() method. Then do the following:
KeyboardDevice keyboard = Engine.Services.GetService<KeyboardDevice>();
MouseDevice mouse = Engine.Services.GetService<MouseDevice>();
FPSCamera cam = (FPSCamera)Engine.Services.GetService<Camera>();
Vector3 inputModifier = new Vector3(
(keyboard.IsKeyDown(Keys.A) ? -1 : 0) + (keyboard.IsKeyDown(Keys.D) ? 1 : 0),
(keyboard.IsKeyDown(Keys.Q) ? -1 : 0) + (keyboard.IsKeyDown(Keys.E) ? 1 : 0),
(keyboard.IsKeyDown(Keys.W) ? -1 : 0) + (keyboard.IsKeyDown(Keys.S) ? 1 : 0)
);
cam.RotateTranslate(new Vector3(mouse.Delta.Y * -.002f, mouse.Delta.X * -.002f, 0), inputModifier * .05f);
if (mouse.WasButtonPressed(MouseButtons.Left))
{
PhysicsActor act = new PhysicsActor(
Engine.Content.Load<Model>("Content/ig_box"),
new BoxObject(new Vector3(.5f), cam.Position, Vector3.Zero));
act.Scale = new Vector3(.5f);
act.PhysicsObject.Mass = 1000;
Vector3 dir = cam.Target - cam.Position;
dir.Normalize();
act.PhysicsObject.Velocity = dir * 10;
}
And that’s all there is to it! Press the mouse button and you should shoot a box away from the camera!
Download the Code for this Chapter
Back to Game Engine Tutorial Series

I have a question. MathUtil has no Vector3ToMatrix method.
I can’t find it.
and rotation is not matrix. I think this means RotationMatrix.
Read 6.5 below
is there a reason you dont use Quaternions for rotation?
1. We don’t have to calculate the matrices using Matrix.CreateFromYawPitchRoll each frame to draw each object, we just use the matrix we already have.
2. JigLibX uses matrices, so by using them we can save conversions when interfacing with it.
Ah ha. Well that makes sense I guess. Just thinking about doing a simulation game like a flying game or somthing =P
It seems that on the xbox 360, the collision is somewhat broken. I run this on it and about 3/4 of the boxes that i shoot are just flying right through everything. I wonder if its an issue with the JigLibX library on the 360. Any ideas why this is?
Hmm, looks like its something to do with the size of the object. If i scale the box to 2.0f then it runs fun. Weird.
I tried running the program, but I couldn’t leave it, not even with Task Manager (mainly because the mouse pointer wouldn’t move). I had to force my laptop off in order to quit it (a real pain).
My point is, shouldn’t you make a command for quitting the program with the press of a button (like Esc or something)? Just asking.
Alt + F4
Didn’t know that.
Thanks!
How do you add dynamic light affects and water affects?
got my implementation working smoothly. Altho for me drawing boxes is 1 behind. I see 8 instead of 9 at the start. when I fire, it puts the 9th box, and some invisible one knocks it over.
Not sure where that goes wrong. (Had this before adding inputhandling)
When I fire now, it puts a box at the previous target and then fires another invisible one.
Any clue where to fix this?
Next stop for me: build in inverted boolean and expand the rotatetranslate method to support that (Y axis).
(small note: invert the x rotation)
If people want I could supply the piece of code
Is there a way for me to instead of using a FPS Camera, create a camera class thats also for 3rd person and activate it via a key pressed… Eg: click once for on and once for off.
Does someone know how to attach the camera to the physic-boxes? Ive tried it but the camera just flew out into space… where no camera has been before…
I made a var to store it and setthe cams pos with to the pos of the box.
Hi,
Very nice tutorials. I don’t understand the math in your camera classes, can you please give me an explanation? In the Camera class for example there is a statement saying “rotationMatrixCopy.Forward = newForward;”
Why do you assign a vector to a matrix? This does not make sense to me for i’m not very well at home in vector math…can you maybe give a site where i can find these things? I tried to google it but all i get is very basic linear algebra stuff and nothing that can explain what is going on here.
Thanks,
Steven
lol funny ur code dont even load what a doosh bag
//Exit
if (Engine.Services.GetService().WasKeyPressed(Keys.Escape))
Exit();
Nothing wrong with the code, but you need to start at Tutorial #1 and work forward. Given the date of your post I’m assuming you’re using XNA 4.0 which will require several code changes because of breaking changes in the framework, as well as an updated JigLibx.