third person camera

Started by
6 comments, last by Psybr 21 years, 11 months ago
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.
Advertisement
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.


TLC
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?
--------------------------www.4bitterguys.com
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.


TLC
if your using openGL, theres a good set of tutorials on cameras (including 3rd person) and all sorts of things at www.gametutorials.com
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	Pitch;	D3DXMATRIX	Yaw;	D3DXMATRIX	Roll;	D3DXMATRIX	Rotation;	D3DXVECTOR3	Eye;	D3DXVECTOR3	LookAt; 	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_Near,				    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]
~CGameProgrammer( );Developer Image Exchange -- New Features: Upload screenshots of your games (size is unlimited) and upload the game itself (up to 10MB). Free. No registration needed.
Thanks, that''s really helpful!
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( );

~CGameProgrammer( );Developer Image Exchange -- New Features: Upload screenshots of your games (size is unlimited) and upload the game itself (up to 10MB). Free. No registration needed.

This topic is closed to new replies.

Advertisement