In previous lessons, you've built a car using basic game objects, got the car moving, and added a track for the car to drive around. What we'll do now is to create a timer to record the current lap time. We'll also have a previous lap time, and the best lap. So, three times. And we'll display them all on screen.
Actually, the first thing we need for a timer is another cube! This cube will act as a trigger. When you pass through the cube, the timer will start. Pass through it again and the timer will reset, ready for a new lap time.
So add a new cube to your Scene (you should know how to do this by now). Rename it to StartLine. Now move it in front of your car, and resize so it's the width of the track:
We set the Transform values for the start line cube to these:
With your StartLine cube selected, locate the Box Collider component in the Inspector. Put a check in the box for Is Trigger:
Because it's a trigger, we'll be able to pass straight through this cube. And it can accept scripts, so we'll attach a timer to it. Passing through the cube will start the timer.
Notice that the cube also has a Mesh Renderer. If you uncheck this, the cube will look as though it has vanished:
It hasn't vanished, though. And any scripts attached to the cube will still work. You can keep it checked, however, just for testing purposes, so that you'll know where the start line is.
OK, now that we have our start line setup, let's write some code.
With your StartLine cube selected, click the Add Component button
in the Inspector. Type New Script into the search box and create
a new script. Call it Timer. Now open up your script in your
coding editor. (If your new script is not in your Scripts folder, simply
drag it in there to tidy up your Projects > Assets folder. You can
double-click a script to open it up.)
You don't need the Start method, so you can delete that. And any comments that are there by default.
One handy method we can use is an inbuilt one called OnTriggerEnter. Because we set up our StartLine cube to have a trigger, the OnTriggerEnter method fires as soon as the cube detects something entering it.
So, outside of your Update method, type the word OnTriggerEnter. Press the TAB key on your keyboard and Visual Studio will complete the method for you. If not, just enter all this:
private void OnTriggerEnter(Collider other)
We're going to need a few variables, so set these up at the top of your code, inside of the class:
private float startTime;
private float elapsedTime;
private bool hasStartedLap = false;
The first two will be used to store the time. The third variable is used as a flag to check if we have started or not.
Your coding window should look like this:
In between the curly brackets of OnTriggerEnter, enter these two lines:
hasStartedLap = true;
startTime = Time.time;
First, we set hasStartedLap to true. Next, store the start time. This is done using the inbuilt Time.time.
Now go to the Update method. In between the curly brackets of the Update method, enter this if statement:
elapsedTime = Time.time - startTime;
If hasStartedLap is true, then the if statement will be activated. If it's false, it won't be. In between the curly brackets of the if statement, we first have this:
elapsedTime = Time.time - startTime;
We take the current time with Time.time again. Then we deduct startTime from this. The start time is recorded when OnTriggerEnter is called. And OnTriggerEnter will be called when our car passes through the cube.
Once we deduct the startTime from the current time (Time.time), we can store it inside of the elapsedTime variable.
The final line is a debug line:
You'll see what this does in a moment. But it's just for testing purposes, so we can see that something is happening. Soon, we'll display the times on screen. We'll then comment out the debug lines.
Save your code and go back to Unity. Before playing your game, click on the Console tab next to the Project one:
If you can't see a Console tab, click on Window on the menu at thy top of Unity. From the Window, select Panels > Console:
Now start your game. Drive forward through your StartLine cube and watch the Console window at the bottom. You should see the time start, as in the video below. Notice how the timer resets when the car passes through the start line a second time:
OK, now that the timer works, let's display the lap time on screen.
Unity User Interface
To get the score on screen, we need a UI component. From the menu at the top of Unity, click on Game Object. From the Game Object menu, select UI > Text (we'll do the TextMesh Pro in a later tutorial.):
When you click on Text, what you'll get is a canvas with a Text component inside of it. (There's also something called EventSystem, but don't worry about this.)
Rename the Text component to LapTimeText:
The Canvas looks really big in Scene view, so you have to really zoom out to see it all:
The white square in the image above is the canvas. The small rectangle in the bottom left of the white square is your gaming surface. That's how far you have to zoom out!
Now use your right mouse button to rotate the canvas. Hold down your middle mouse button to pan. Turn the canvas and you can get it looking like this (but don't worry if it doesn't):
Our Text component, the one we renamed to LapTimeText, is sitting in the middle of the canvas. (It might be in the bottom left, for you.) It has the default text of New Text. You can change the position of the text by moving the red and green arrows above. Or you can type in a new position using the Inspector.
With your LapTimeText object selected, have a look at the Inspector on the right. In particular, have a look at the top of the Inspector. You'll see values for PosX, PosY, PosZ, a Width and a Height (don't worry if your value aren't the same as the ones below. We're going to change them.):
Change the positions to these:
And change the Width to 200 and the Height to 30. The top of your Inspector will look like this:
Now click on your Game tab. This will show you what your new text looks like:
If you don't like the position of your text, play around with the PosX and PosY values. Let's change the size and colour, though.
Go back to Scene view. With your LapTimeText object still selected, scroll down in the Inspector and locate the Text section:
Delete the default New Text and type Lap Time:.
You can change the Font to anything you like, but we'll keep it on Arial. Change the Font Size to 18, though. Then click the white stripe in the Color section. You'll get a color wheel where you can select a new color for your text. We've selected white. Here's the Inspector now:
Click back on Game view to see what your text looks like:
OK, let's go back to the coding window and add some more lines to our script.
Scripting for UI Elements in Unity
We need to use Unity's UI library. So add that using statement to the top of the code:
Inside of the Class, add a new variable, just under the three you already have. Add this:
public GameObject lapText;
This time, we want a public variable. Notice that the type is GameObject, instead of float or bool. This means that we'll be able to assign a game object to this lapText variable. A game object like the text area of a canvas, for example.
Only one more line to add. In your Update method, and inside of the if statement, add the following line:
lapText.GetComponent<Text>().text = "Lap Time: " + elapsedTime.ToString();
Your coding window should look like this: (The new lines are highlighted. You can comment out your Debug line.):
The GetComponent<Text>() part of the line refers to the whole of the Text component, the one you saw in the Inspector. This:
The .text part after the round brackets refers to just the text part of the Text component. This:
We set some new text for it after the equal sign:
= "Lap Time: " + elapsedTime.ToString();
We're joining the direct text "Lap Time:" with our elapsedTime float variable. Because it's a float, we need to convert it to text before we can place it on screen. This is done with the ToString method.
We now need to assign a game object to our script. To do that, save your code and go back to Unity. In the Hierarchy, select your StartLine cube.
If you extend the Script section in the Inspector, you should see that lapText variable we set up:
Lap Text is waiting for a game object to be dragged onto it. The game object we need to drag onto it is our LapTimeText object. In the Hierarchy, hold down your left mouse button on the LapTimeText object. Keep it held down and drag it onto Lap Text, where it says None (Game Object):
Let go of your left mouse button and you should see LapTimeText appear in place of None (Game Object):
Now we should be good to go.
Start your game. When you drive your car through the start line, you should see the timer activate in the top left of your screen, as in the short video below: (20 seconds)
When you complete a lap and go through the StartLine cube again, the timer should reset.
Nice, so far! What we'll do now is to record the previous lap and place it onto a text panel of its own. Then we'll record the best lap. We'll do all that in the next lesson below.