The Secrets Of Set Camera To Follow
All 3D games which have a third person camera view need the camera to track the player's character. The game isn't much use if the character moves off into the distance leaving the camera just sitting there...
So, how do you make the camera follow the player?
Well, there are two ways. One is to use maths and calculate the position of the camera in 3D space based on the current player's position.
This isn't that difficult as the Dark Basic functions Object Position X(), Object Position Y() and Object Position Z() will instantly tell us where the player is whereas Camera Position X(), Camera Position Y() and Camera Position Z() give us the same information but for the camera.
Given this information, and some maths calculations we can calculate the required new position and angles for the camera.
But, all the maths involved isn't necessary at all as there is a Dark Basic command called Set Camera To Follow which does everything for you. It has a bewildering list of parameters you have to use to make it work and DB's built-in help files don't really do a good job in explaining how it all works. As such many users don't use it.
Hopefully, this tutorial will clear things up a bit.
Syntax:
The Set Camera To Follow command is used in the following way:
Set Camera To Follow X#, Y#, Z#, Angle#, Camdist#, Camheight#, Camsmooth#, ColFlag
(All parameters are float values apart from ColFlag which is integer and can be either a 0 or a 1).
X, Y & Z
These are set to the X, Y & Z co-ordinates of the object you want the camera to follow. You can use the float variables you use to position the object you are tracking, or if you use the turn/rotate commands and then Move Object instead, Object Position X(), Object Position Y() and Object Position Z() can be used.
Angle
This is the angle that you want the camera to be at as it tracks the object and is normally set to the same angle as the object being tracked. The camera then stays behind the object.
If you want the camera to track the object from the side similar to the way a TV camera tracks horses in a horserace, you need to add 90 or 270 to the object's angle - depending on the side of the tracked object you want to be. Adding 180 will position the camera in front of the object moving backwards.
Camdist
This is the number of 3D units that will be between the object being tracked and the camera.
Camheight
This is the one parameter that many newcomers misunderstand and as such makes it look like the command doesn't work properly. Many assume it is the height above the object being tracked, whereas in reality it is actually the absolute height of the camera in the 3D world. You therefore have to set this to the object's height plus the required additional height of the camera.
Camsmooth
This parameter sets the speed that the camera locks onto the specified tracking position. The slower this happens, the smoother the effect. The value range can be from 1 where there is no smoothing to 100 which is a lot of smoothing. For a normal smoothing effect, a value of around 10-15 is a good place to start.
ColFlag
This flag turns camera collision on. Setting it to 1 will prevent the camera from entering areas defined as static collision boxes. Setting it to 0 turns collision off.
It's important to note however that this collision has no effect with matrices - the camera will still pass through them if the Camheight parameter isn't set high enough.
Sync On
CLS 0
Hide Mouse
Make Matrix 1,500,500,20,20
Make Object Cube 1,1
Color Object 1,RGB(255,0,0)
Position Object 1,250,Get Ground Height(1,250,250)+1.0,250
Camdist# = 15.0
TrackAngle = 0: Rem 0 - Behind, 180 - Front, 90 & 270 - Sides
ReqCamHeight# = 5.0
Camsmooth = 10
ColFlag = 0
Do
MMx = MouseMoveX()
Y# = WrapValue(Object Angle Y(1)+MMx): Yrotate Object 1,Y#
Move Object 1,.4
ObjX# = Object Position X(1): ObjZ# = Object Position Z(1)
ObjHeight# = Get Ground Height(1,ObjX#,ObjZ#)
Position Object 1,ObjX#,ObjHeight#+1.0,ObjZ#
Camheight# = ObjHeight#+ReqCamHeight#
Set Camera To Follow ObjX#,ObjHeight#,ObjZ#,WrapValue(Object Angle Y(1)+TrackAngle),Camdist#,Camheight#,Camsmooth,ColFlag
Sync
Center Text 320,0,"Steer The Cube With The Mouse"
Loop
A brief description of the lines which make up the main Do..Loop:
We use MouseMoveX() to store the left/right mouse movement in MMx and add that to object 1's Y angle. This steers the cube.
Next we move the cube and grab it's new X and Z position in order to use Get Ground Height() which tells us the cube's height. We add 1.0 to this value when re-positioning the object. This ensures that the cube always stays 1.0 3D units above the matrix.
Finally, we add the required height to whatever height object 1 is currently positioned. This means that as the cube moves up and down (over hills for example), the camera always stays a fixed distance above the object.
Example Code For DBPro:
As DBPro is considerably faster than DBC, the previous code snippet runs too fast in DBPro. So, here's the same code snippet but adapted to run better in DBPro. To kill two birds with one stone, it also uses the keyboard to steer the cube instead of the mouse, so if you need this in a DBC program, just alter the first four lines of the main loop accordingly (altering the rotate angle and move speed to suit).
Rem Example For DBPro With Keyboard Cursor Keys Steering
Sync On
CLS 0
Hide Mouse
Make Matrix 1,500,500,20,20
Make Object Cube 1,1
Color Object 1,RGB(255,0,0)
Position Object 1,250,Get Ground Height(1,250,250)+1.0,250
Camdist# = 15.0
TrackAngle = 0: Rem 0 - Behind, 180 - Front, 90 & 270 - Sides
ReqCamHeight# = 5.0
Camsmooth = 200
ColFlag = 0
Do
rem MMx = MouseMoveX()
rem Y# = WrapValue(Object Angle Y(1)+MMx): Yrotate Object 1,Y#
If LeftKey()=1 Then Y# = WrapValue(Object Angle Y(1)-.3): Yrotate Object 1,Y#
If RightKey()=1 Then Y# = WrapValue(Object Angle Y(1)+.3): Yrotate Object 1,Y#
Move Object 1,.05
ObjX# = Object Position X(1): ObjZ# = Object Position Z(1)
ObjHeight# = Get Ground Height(1,ObjX#,ObjZ#)
Position Object 1,ObjX#,ObjHeight#+1.0,ObjZ#
Camheight# = ObjHeight#+ReqCamHeight#
Set Camera To Follow ObjX#,ObjHeight#,ObjZ#,WrapValue(Object Angle Y(1)+TrackAngle),Camdist#,Camheight#,Camsmooth,ColFlag
Sync
Center Text 320,0,"Steer The Cube With The Mouse"
Loop
Useful Pointers When Using Set Camera To Follow
As Set Camera To Follow has a smoothing parameter, if it is used, it is not a 'call once' command. For anything to happen, it has to be called continuously until the camera eventually reaches it's destination.
If the object being tracked is moving, this may never happen until it comes to a halt. When this happens, the camera will slowly come to a halt in the required position - depending on the value of the CamSmooth value.
This command can therefore be used with non-moving objects to provide smooth transitions between different views.
For example, in the case of a boxing ring where the camera is showing a full front view. You might want to switch to a side view and rather than instantly switch, have the camera swing smoothly around to the new position. With Set Camera To Follow, this can be done by simply altering the angle value.as the following simple example shows:
Gosub Setup
Gosub Make_Objects
ObjX# = Object Position X(1)
ObjY# = Object Position Y(1)
ObjZ# = Object Position Z(1)
ObjAngle# = 0.0
Camdist# = 6.0
Camheight# = 4.0
Camsmooth = 10
ColFlag = 0
Do
If Inkey$()=" "
Inc ObjAngle#,90.0: If ObjAngle#=360.0 Then ObjAngle#=0.0
Repeat
Until Inkey$()=""
Endif
Set Camera To Follow ObjX#,ObjY#,ObjZ#,ObjAngle#,Camdist#,Camheight#,Camsmooth,ColFlag
Point Camera ObjX#,ObjY#,ObjZ#
Sync
Center Text 400,0,"Press Space To Rotate The Camera View"
If ObjAngle#=0.0 Then Center Text 400,580,"Front View"
If ObjAngle#=90.0 Then Center Text 400,580,"Left View"
If ObjAngle#=180.0 Then Center Text 400,580,"Back View"
If ObjAngle#=270.0 Then Center Text 400,580,"Right View"
Loop
Make_Objects:
Make Object Box 1,5,1,5
Color Object 1,RGB(0,128,0)
Make Object Box 2,.1,1,.1
Color Object 2,RGB(255,0,0)
Position Object 2,-2.45.5,1,2.445
Make Object Box 3,.1,1,.1
Color Object 3,RGB(255,0,0)
Position Object 3,2.45.5,1,2.445
Make Object Box 4,.1,1,.1
Color Object 4,RGB(255,0,0)
Position Object 4,2.45.5,1,-2.45
Make Object Box 5,.1,1,.1
Color Object 5,RGB(255,0,0)
Position Object 5,-2.45.5,1,-2.45
For N=6 To 11
Make Object Box N,4.95,.02,.02
Next N
For N=12 To 17
Make Object Box N,4.95,.02,.02
YRotate Object N,90
Next N
Position Object 6,0,0.8,2.45
Position Object 7,0,1.1,2.45
Position Object 8,0,1.4,2.45
Position Object 9,0,0.8,-2.45
Position Object 10,0,1.1,-2.45
Position Object 11,0,1.4,-2.45
Position Object 12,-2.45,0.8,0
Position Object 13,-2.45,1.1,0
Position Object 14,-2.45,1.4,0
Position Object 15,2.45,0.8,0
Position Object 16,2.45,1.1,0
Position Object 17,2.45,1.4,0
Return
Setup:
Set Display Mode 800,600,32
Sync On
Return
That's it for now. I'll add further uses for Set Camera To Follow along with examples if and when I think of them.
TDK_Man