How We Implemented Vehicle Mechanics in Our Game — Part 4
This article is about the development process of our first game. During the process, we are learning how to use Unity & Blender from scratch to create everything you see in the article, enjoy!
Introduction
Welcome back!
In the last part we looked at fixing bugs in the vehicle system thus far, and this time we are going to implement automatically moving the camera to the correct position depending on what the player needs to see.
Moving the Camera
As you can see in the images above, you cannot see the entire vehicle when you are using it. To solve this we will work on a system to automatically move the camera further back when using a vehicle and closer again when walking.
To change how the camera works, let’s first look at how it’s set up currently;
The camera is not a child object of the player. Instead, the camera script makes the camera look at and follow the player around. This is what the current script for the camera looks like:
The script uses the Vector3 variable offset
to determine how far away from the player that the camera should be at all times and at which orbit to rotate around the player. The value for this variable is currently set in the Start
method.
My theory for how to implement moving the camera further back automatically when using vehicles is to manipulate one of the Vector3 axes and move the camera further away or closer depending on if the player is using a vehicle or walking.
To begin experimenting with a solution, let’s print out a message to the log to find out what value offset
is given at the start of the game;
After clicking play and starting the game in the Unity editor, the camera script printed out (-0.6, 5.4, 9.2)
. This is the current distance unit that the camera uses to determine how far away from the player it should be.
Let’s move the camera a bit back and see what happens.
After moving the camera back and clicking on the play button again, the script printed out (-0.8, 9.4, 16.7)
to the log, having moved from (-0.6, 5.4, 9.2)
at the previous position.
If we can learn anything from this, it would be that the camera has to move in three axes at the same time to move further back since the camera is tilted at an angle.
This makes it a bit more difficult to figure out how much to move on each axis to get the camera moving in a straight line back and forth than if there was just a single axis to manipulate.
To try and make the implementation as simple as possible, I’m going to try another theory instead;
I will create two empty game objects as child objects of the player at the positions where I want the camera to be when walking and using vehicles respectively. When switching between walking and using a vehicle, the camera should store the positions of both game objects and teleport to the appropriate one.
First, let’s create an empty game object at the current position of the camera and position it as a child object of the player.
Next, we will do a little bit of trial and error to find out how far back from the player the camera should be so that the entire vehicle can be seen when it is being used.
After that, we will create a game object that represents the position of the camera when it is further away from the player, and then move it up in the hierarchy so that it is no longer a child object, and copy the position to the clipboard.
The reason we don’t want the game object as a child object when we copy its position is that we want the world space position instead of the local space position.
For more information about world space and local space and their differences, see this great article by Matthew Clark.
Once that is done, we undo all of the camera changes so that the camera is in the same position as when we started.
To restore the position for when the camera should be further away from the player, we recreate the game object from before and paste the position from the clipboard and finally make it a child object of the player.
To summarize what we just did
- Moved the camera back far enough to see the whole vehicle
- Created an empty game object at that position
- Copied the position of that game object to the clipboard
- Undid all of the changes thus far
- Recreated the game object from step 2
- Pasted in the position from step 3
- Made it a child object of the player
This means that we now have 2 new child game objects of the player; one to store the position for when the camera should be close to the player and one for when the camera should be further away.
For the next step, I renamed the variable offset
to offsetClose
and created the new variable offsetFar
. These two variables will store the Vector3 offsets to the player.
I also created the variables cameraPositionClose
and cameraPositionFar
that will represent the positions of the game objects that we just created and I used [SerializeField]
when declaring them so that I can easily set their values in the Unity editor.
The next step of the process will be to set the values for the variables offsetClose
and offsetFar
in the Start method.
Teleporting and Rotating the Camera
Currently, the rotation of the camera works by using Vector3 Slerp to rotate the camera while looking at the player and using the offsetClose
variable to keep the correct distance from the player at all times.
My theory for rotating the camera while using vehicles is to select whether to use offsetClose
or offsetFar
based on if the player is using the vehicle so that the camera will rotate around the correct distance automatically.
In the code block below, I have created the local variable offset
and set it to the value of either offsetClose
or offsetFar
based on whether the player is currently using a vehicle or not.
As you can see, this solution switches the camera position to move the camera back when using a vehicle and moves it closer when not using a vehicle as it should. However, there does seem to be a bug with the script since it is not possible to rotate the camera when using the vehicle.
So if we look at the function responsible for rotating the camera, it only uses the variable offsetClose
for rotation;
My first thought is to try and add the same variable that we used in the previous function that we worked on, and see if that can solve the problem;
Unfortunately, now it’s impossible to rotate the camera, so that didn’t quite work as I expected.
So far, we do know that the rotation worked while walking when the script only used offsetClose
. Let’s revert the changes I just did try replacing offsetClose
with offsetFar
this time instead.
So now we have managed to produce the opposite scenario; the camera can be rotated when using a vehicle but not when walking.
From this, we can gather that we cannot change which object we can rotate after the game has started. Instead, why not try and rotate both of them at the same time regardless of whether that specific camera position is being used or not?
If this theory succeeds, both camera points should always be in the correct place and be rotatable.
Conclusion
The camera now moves to the correct position automatically and rotates without problem, so this marks the end of part 4!
The list of things to implement for vehicles is getting shorter and shorter, but we still have some ways to go yet. These are the features that remain to be implemented before the vehicle system is ready:
- Implement proper colliders for vehicles, so that they can bump into things and react somewhat realistically and use some kind of buoyancy system
- Implement specific animations for using vehicles
- Implement a steering system where speed and direction are influenced by the wind rather than controlled directly by the player.
See you in part 5!