Spanish Version

Camera Types

A lot of people have asked me how to make certain types of camera, like third-person cameras or the kind that are used in a fighting game. In this article I will try to explain how to create these two kinds of camera.

Third-person camera

This is used in racing games (Need For Speed) and in "over-the-shoulder" games (like third-person shooter games). Let's explain how this is done.
First thing is to know the character's location and where it's looking at. You can get this information from the model's LocalWorld matrix.

Vector3 position = new Vector3(localWorld.M41, localWorld.M42, localWorld.M43);
Vector3 lookAt = new Vector3(localWorld.M31, localWorld.M32, localWorld.M33);


With this we can now calculate a point at the back of the model by subtracting the normalized lookAt vector from the position, and multiplying it by a value. To normalize a vector we can use the Vector3.Normalize method.

TerceraPersona.png

There is a faster way to do this. If we use the Vector3.TransformNormal method, we only need to set a vector with the offset that we want to apply to the position, and it will give us another vector. If we now subtract this vector from the position, we will obtain the desired position behind the model.

Vector3 offsetPlayer1 = new Vector3(0, -5, 20);
offsetPlayer1 = Vector3.TransformNormal(offsetPlayer1, player1.localWorld);
Vector3 pivotPlayer1 = player1.position - offsetPlayer1;


Now we have the position where we want the camera to be. We can use the model's position for the camera's lookAt. The problem with this is that the camera's movements would be rather "rigid", and we don't want it to seem that the character and the camera are attached. To solve this, we will add a simple interpolation between the camera's current position and the position where it should be. This way, the camera will move smoothly and it will eventually be in the right position.

Position -= (Position - pivotPlayer1) / 10;
View = Matrix.CreateLookAt(Position, player1.position, Vector3.Up);


DivideDistance.png

As you can see, we divided the distance between the pivot, which is where the camera should be, and the model's position by 10. We then make the camera's position advance towards the pivot's in steps that are 1/10 of the current distance between them. This will create an interesting effect, since it will slow down as the distance gets smaller, and we will have the feeling that the camera's movement accelerates and decelerates.

Fighting game camera

In games like Tekken or Budokay, both players always appear on the screen, so the camera zooms in or out depending on the distance between players.
First thing we want to find out is where the camera should point at. The camera should look at a point in between both players, and to calculate this we have to add the model's position vectors and divide the result by 2.

Vector3 middle = (player1.position + player2.position) / 2;


FightLookAt.png

To calculate the camera's position, we will first have to calculate the plane where the models are and then we can set the camera with the plane's normal.

Let's caulculate one of the player's vector:

Vector3 playersVector = player1.position - player2.position;


Now we can get the vector product of this vector and the Vector3.Up, and use it to calculate the normal vector of the plane:

Vector3 normal = Vector3.Cross(playersVector, Vector3.Up);
normal = Vector3.Normalize(normal);


We now calculate a value, which changes depending on the distance between players, and multiply it by the normal:

float offsetFactor = playersVector.Length() + 50;
Position = middle - (normal * offsetFactor);


CameraFight.png

Now we have all we need to update our camera's View matrix:

View = Matrix.CreateLookAt(Position, middle, Vector3.Up);


An example of these cameras: Example


Traslated by Juliet R. Moreiro Bockhop

Created by Javier Cantón Ferrero.
MVP XNA-DirectX 2007/2009
MSP 2006/2008
Date 28/07/2008
Web www.codeplex.com/XNACommunity
Email javiuniversidad@gmail.com
blog: mirageproject.blogspot.com

Last edited Aug 17, 2008 at 9:35 PM by Juliet, version 10

Comments

No comments yet.