Recording Previous Lap, Best Lap times

OK, we displayed a lap time on screen in the last lesson. In this lesson, we'll display a previous lap time and a best lap time.

In the Hierarchy on the left of Unity, select your LapTimeText object. Duplicate this by pressing CTL + D on your keyboard (or right click and select Duplicate from the menu that appears). Rename your new Text panel. Call it PrevLapTime. Your Hierarchy should look like this:

A Text component duplicated

With PrevLapTime selected, move it down a bit. You can keep the PosX at the same value in the Inspector. Change the PosY value to 187. Change the Text to Last Lap:.

Changing the values of a text component

Click on the Game tab and check your work:

Game user interface showing lap time and last lap times

Unity Tags

For our last lap to work, we need something called a Tag. Don't worry. These are quite easy to set up. But what they do is to allow you to tag a game object and then write code to single out that tagged object.

Unity comes with some inbuilt tag names already set up. To see them, switch back to Scene view. Select your Car object in the Hierarchy. Now look at the top of the Inspector. You'll see a drop down for Tag:

A Player tag in Unity

Most game objects are untagged by default. Click the dropdown to see a list of tags you can choose from. Game objects can have the same tags. For example, if you have lots of enemies, they can all have the Enemy tag. Then, in your code, you can deal with all objects that have the tag enemy. For our Car object, select the tag Player:

The Tag dropdown list

But if you wanted to, you could create your own tag. (you can create as many tags as you want). Click the Add Tag option at the bottom of the menu. You'll see this screen:

The Add Tag button indicated

Click the Plus button, indicated by a red square in the image above. You'll then see a small dialogue box appear. This one:

Saving a new tag

Enter a new name for your tag and click the Save button.

In the Hierarchy, click back on your Car object. Now, in the Inspector, click the dropdown to see your new tag:

A nw tag added to the list of tags

But we'll stick with the Player tag.

Go back to your coding window. Now notice what's between the round brackets of your OnTriggerEnter method:

Collider other

Collider is the object; other is just the name of this object. (You could change other to anything you like.) Whatever sets off the trigger method (collides with it) ends up in the other variable. You can write code to detect what triggered the method. This can be done with an inbuilt method called CompareTag:

if (other.CompareTag("Player") ) {
}

If you wanted to detect if, say, an enemy had wandered into your trigger, you could write this:

if (other. CompareTag("Enemy") ) {

//DO SOMETHING

}

We only want to start our timer if the player sets off the trigger. So, adapt your code from this:

private void OnTriggerEnter(Collider other)
{

hasStartedLap = true;
startTime = Time.time;

}

To this:

private void OnTriggerEnter(Collider other)
{

if (other.CompareTag("Player")) {

hasStartedLap = true;
startTime = Time.time;

}

}

Now add a new GameObject variable at the top of your code:

public GameObject prevLapText;

Back to the CompareTag if statement. Add this line just below the two you already have:

prevLapText.GetComponent<Text>().text = "Last Lap: " + elapsedTime.ToString();

This is just the same as before, when we accessed the Text component for the lap time. Nothing new here. But your code should look like this (the new lines are highlighted):

Unity C# code to add previous lap text

Save your work and go back to Unity. Like before we need to drag a game object onto the script.

In the Hierarchy, select your StartLine object. Expand the Canvas item and drag PrevLapTime onto the Prev Lap Text item in the Inspector, as shown in the image below:

Dragging a Text game object onto the Inspector

The Timer (Script) part of the Inspector will then look like this:

The Inspector showing a Text component added

Now start your game. When you've completed one lap, the result should appear in your Last Lap text area in the top left, as shown in this video: (20 seconds)

 

Best Lap

Now we need to record the best lap. The coding for this is a little trickier as we need to use something called a List. It's not too difficult, though.

First of all, in the Hierarchy, select your PrevLapTime Text component. Duplicate this, just like you did before. Rename it BestLap. In the Inspector, change the text to Best Lap:. Set the PosY value to 154. This will move it down a little, so that's under the Last Lap item.

Click the Game to see what it looks like:

A best lap text item added to the Hierarchy

Now go back to your coding window. Set up a new GameObject variable called bestLap:

public GameObject bestLap;

Just below that, set up a List with this line:

List<float> besTimes = new List<float>();

If you're not sure about lists in C#, read all about them here on our site:

C# Lists (Opens in new tab)

The way this will work is just to put all the lap times into our list. Then we sort the list. The lowest time will then be at the top of the list.

The way you add items to a list in C# is with the Add method (don't add this to your code just yet):

bestTimes.Add(elapsedTime);

Here, we're just adding elapsedTime to our bestTimes list.

However, we don't want to record a time of 0, which is what would happen on the first lap. So we can exclude a lap time of zero with an if statement. Add this to your OnTriggerEnter method, just below the prevLapText.GetComponent<Text>().text line:

prevLapText.GetComponent<Text>().text = "Last Lap: " + elapsedTime.ToString();

if (elapsedTime != 0) {

bestTimes.Add(elapsedTime);

}

Now we need to check the list to see if it's greater than zero. If it is, then we can sort the list and display a best time. Add this new if statement to your code, just below the first one:

if (bestTimes.Count > 0) {

bestTimes.Sort();
bestLap.GetComponent<Text>().text = "Best Lap: " + bestTimes[0].ToString();

}

Lists have an inbuilt method called Sort that you can use to sort your list. We can use Sort after our bestTimes list:

bestTimes.Sort();

Simple as that! (If you wanted to do a reverse sort, use Reverse instead of Sort.)

The final line in the if statement is where we access the Text component again. This time, note what comes after the equal sign:

= "Best Lap: " + bestTimes[0].ToString();

Because bestTimes is a list, you can get at individual items in the list with square brackets. The item at the top is [0], the second item [1], the third item [2], and so on. If you wanted to display the top 5 best times, you'd do this:

bestTimes[0].ToString();
bestTimes[1].ToString();
bestTimes[2].ToString();
bestTimes[3].ToString();
bestTimes[4].ToString();

Anyway, your code should look like this ( the new lines are highlighted):

Unity C# code to record a best lap

Just like we did before, we need to drag the new Best Lap text object onto the script. So, save your code. Go back to Unity. In the hierarchy, select your StartLine object. In the Canvas, drag your BestLap object onto the Best Lap item in the Inspector:

Dragging a Best Lap text item onto the Inspector

Now play your game. You might need to do a few laps, but when you do, you should find the best lap recorded nicely, as in the video below: (60 seconds)

 

In the video above, we done a slow lap, fast lap, and then another slow lap. (We're hiding our chicanes, though, and have left the starting line cube with its Mesh Renderer on.)

In the next lesson below, we'll add a bit of sound.

<--Back to the Unity 3D Course Contents Page