This topic is now archived and is closed to further replies.

third person camera

This topic is 5698 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

How would you implement a camera that followed a character around? e.g. when the character moves, the camera follows a distance behind it and maintains the same orientation as the character, allowing the player to see what the character sees.

Share this post

Link to post
Share on other sites
Guest Anonymous Poster
Assuming you''re using one of those LookAt helper functions that come with OGL or D3D:

1. Pick a lookat target (either an actual object or just some space a set distance in front of your target) [Vt]
2. Set one end of the vector right above your player [V0].
3. Calculate the unit vector going from [V0-Vt].
4. Set your camera position at dist*[V0-Vt] where dist is the distance you want the camera to be behind the player.
5. Use 1st order lag to smooth out the camera movement.


Share this post

Link to post
Share on other sites
Could you clarify what you mean by 1st order lag? Do you just mean take the average camera vector of the last, say, 30 frame''s camera vector''s? Or is it something more complex than that?

Share this post

Link to post
Share on other sites
Guest Anonymous Poster
Sorry. First, I should point out that it''s best to use time as units instead of frames. That way, should your framerate drop at certain times, the movement doesn''t get too jerky. Unpredictable motion (to the user) is probably one of the main causes of motion sickness.

With that out of the way, 1st order lag is:

Vreqpos = dist*[V0-Vt]; // from before
Vpos = K*(Vreqpos - Vpos) * dt;

where K is some constant gain, and dt is just the elapsed time since the last frame.

In this case, the camera will be C1 continuous (position). And it works generally for most games. If however, Vreqpos moves around a lot, the velocity (basically the K*( ) term) will become jerky again. In this case, you might want to go one level higher and do Vreqvel and Vvel in much the same way to get C2.


Share this post

Link to post
Share on other sites
It's really simple. For the LookAt function (Direct3D's and OpenGL's) you take the eye position relative to the player (which is probably something like {0,0,1} rotated by the camera orientation), multiply it by the third-person follow distance, then add the camera position. For a first-person view, you set that follow distance to zero but use the same equation.

Here is my camera code. It uses D3DX matrix functions but they work with both Direct3D and OpenGL (since they're right-handed). You can pass the matrices directly to the glLoadMatrixf command.

D3DXMATRIX Rotation;

D3DXMatrixRotationX( &Pitch, (float)PI_OVER_180 * -ms_Camera.Pitch );
D3DXMatrixRotationY( &Yaw, (float)PI_OVER_180 * -ms_Camera.Yaw );
D3DXMatrixRotationZ( &Roll, (float)PI_OVER_180 * -ms_Camera.Roll );

D3DXMatrixMultiply( &Rotation, &Pitch, &Yaw );
D3DXMatrixMultiply( &Rotation, &Rotation, &Roll );

LookAt = D3DXVECTOR3( 0, 0, -1 );
Eye = D3DXVECTOR3( 0, 0, 1 );

D3DXVec3TransformCoord( &LookAt, &LookAt, &Rotation );
D3DXVec3TransformCoord( &Eye, &Eye, &Rotation );

LookAt.x += ms_Camera.X;
LookAt.y += ms_Camera.Y;
LookAt.z += ms_Camera.Z;

Eye.x = (Eye.x * ms_Camera.Follow) + ms_Camera.X;
Eye.y = (Eye.y * ms_Camera.Follow) + ms_Camera.Y;
Eye.z = (Eye.z * ms_Camera.Follow) + ms_Camera.Z;

ms_Camera.Eye = vector<float>( Eye.x, Eye.y, Eye.z );
ms_Camera.LookAt = vector<float>( LookAt.x, LookAt.y, LookAt.z );

D3DXMatrixIdentity( &ms_Camera.World );
D3DXMatrixPerspectiveFovRH( &ms_Camera.Project,
ms_FOV * 0.5f,
float(ms_Viewport.Width) / float(ms_Viewport.Height),
ms_Far );
D3DXMatrixLookAtRH( &ms_Camera.View,
&D3DXVECTOR3(ms_Camera.Eye.X, ms_Camera.Eye.Y, ms_Camera.Eye.Z),
&D3DXVECTOR3(ms_Camera.LookAt.X, ms_Camera.LookAt.Y, ms_Camera.LookAt.Z),
&D3DXVECTOR3(0,1,0) );

~CGameProgrammer( );

[edited by - CGameProgrammer on May 7, 2002 1:14:49 AM]

Share this post

Link to post
Share on other sites
Oh, I should add that you can make a small optimization by checking if Follow is zero. If it is, you don''t need to rotate Eye by Rotation or multiply it by Camera.Follow, which saves you a small amount of time.

~CGameProgrammer( );

Share this post

Link to post
Share on other sites