How to make a countdown timer in Unity

How to make a countdown timer in Unity (in minutes + seconds)

In Unity by John5 Comments

A countdown timer is an incredibly common mechanism in game design.

However, while the method of creating a timer and counting it down accurately is quite straightforward; Actually displaying a time value in minutes and seconds can be surprisingly tricky.

We’ve all seen a time display before, so it’s easy to spot if something looks wrong.

And, while there are many methods for displaying a countdown timer, some of them work better than others.

What’s the right way to make and display a countdown timer in Unity?

Making a countdown timer in Unity involves storing a float time value and subtracting the duration of the last frame (the delta time) every frame to make it count down.

To then display the float time value in minutes and seconds, both values need to be calculated individually. Do this by dividing the float time by 60 to get the minutes and use the modulo operation (time % 60) to get the seconds. Finally, use FloorToInt to round each value down and string.Format to display them together correctly in a text field.

While simple to do, there are a few extra steps to remember when making a countdown timer that looks and works exactly as you expect it to.

In this post, I’ll show you exactly how to do just that, step by step:

How to make a timer in Unity (using Time.deltaTime)

The method for making a basic countdown timer in Unity is simple.

Create a float variable to store the amount of time remaining and, every frame, subtract the duration of the previous frame (the delta time) from that amount. Like this:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Timer : MonoBehaviour
{
    public float timeRemaining = 10;

    void Update()
    {
        if (timeRemaining > 0)
        {
            timeRemaining -= Time.deltaTime;
        }
    }
}

This is the basic method forcreating a timer in Unity.

So long as there is time to count down, the timer will run.

However…

Chances are if you’re making a countdown timer, you probably want something to happen when the timer actually reaches zero.

Advertisement

How to trigger an action when the countdown is finished

In the previous example, I used the time remaining to check to see if the timer should still be running or not.

But what if you want to trigger an action when the timer runs out?

For example, you might want to end the game or make the time display flash etc. There’s no point in having a countdown if nothing happens at the end of it!

The easiest way to do this is with an else condition. Like this:

if (timeRemaining > 0)
{
    timeRemaining -= Time.deltaTime;
}
else
{
    Debug.Log("Time has run out!");
}

There’s just one problem with this method.

As soon as the timer runs out, the else condition will continue to be true, every frame.

This means that whatever action that gets triggered when the timer reaches zero will also be triggered every frame afterwards.

Unity countdown timer log firing every frame

Once the timer has ended you probably only want to trigger a final action once.

Probably not what you want to happen.

It’s easy to fix though.

By adding a boolean variable, timerIsRunning, and by wrapping all of the timer’s code inside of an if statement it will only execute it when the timer should be running.

In scripting it looks like this:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Timer : MonoBehaviour
{
    public float timeRemaining = 10;
    public bool timerIsRunning = false;

    private void Start()
    {
        // Starts the timer automatically
        timerIsRunning = true;
    }

    void Update()
    {
        if (timerIsRunning)
        {
            if (timeRemaining > 0)
            {
                timeRemaining -= Time.deltaTime;
            }
            else
            {
                Debug.Log("Time has run out!");
                timeRemaining = 0;
                timerIsRunning = false;
            }
        }
    }
}

This is useful because it allows you to manually control when the timer starts (by setting timerIsRunning to true).

It also means that the final action, which is triggered when the timer reaches zero, only fires once.

Remember to lock the timer to zero when it ends

You may also notice that, when the timer ends, I’ve manually set timeRemaining to zero.

This is because the remaining time will almost always be a negative number when the timer stops. This is because time is subtracted in chunks, equivalent to the duration of the last frame.

I’ve set it to zero when the timer ends because, although it isn’t an issue right now, it can cause a problem when displaying the time value later on.

Which actually brings me to my next question…

How do you convert a float to a time value displayed in minutes and seconds?

Advertisement

How to convert a time value to minutes and seconds in Unity

Countdown timer in minutes and seconds made in Unity

To display minutes and seconds in a time display, each value must be calculated individually.

It seems like it should be a simple task but it can be surprisingly tricky to display a time value in minutes and seconds in Unity.

This is partly because there are so many ways to do it.

I like this particular method because it avoids many of the common problems you are likely to encounter when displaying time correctly, in only a few steps.

Here’s how to do it…

To display the time correctly, both the minutes and seconds need to be calculated individually from the raw time value.

To calculate the minutes divide the time remaining by 60, like this:

float minutes = Mathf.FloorToInt(timeRemaining / 60);

To calculate the seconds, use the modulo operation (%) like this.

float seconds = Mathf.FloorToInt(timeRemaining % 60);

What is the modulo operation?

The Modulo operation is a computing function that returns the remainder, after division, of one number by another.

In this example, modulo is used to return the number of seconds from the total time value that do not make up a whole minute.

Perfect for getting just the seconds of a time display.

For example 62 % 60 would return 2 (1 minute 2 seconds), while 125 % 60 returns 5 (2 minutes 5 seconds).

Any value smaller than a full minute will simply return the same amount of seconds. For example 46 % 60 would simply return 46 (0 minutes 46 seconds).

Finally, in both examples, the values are still floats. Use Mathf.FloorToInt to round them down to the largest integer value.

Here’s what it looks like in scripting:

void DisplayTime(float timeToDisplay)
    {
        float minutes = Mathf.FloorToInt(timeToDisplay / 60); 
        float seconds = Mathf.FloorToInt(timeToDisplay % 60);
    }

You’ll notice in this example, to keep the time display calculations separate from the timer, I’ve placed them inside their own function that takes a single float parameter for the time called timeDisplay.

This will allow you to easily change the time value before displaying it, without interfering with the actual time remaining value.

Why would you want to do that? I’ll explain a little later on.

Calculating the minutes and seconds is, however, only half of the problem.

You will also need to display the time correctly.

Advertisement

How to Display time in text in Unity (using String.Format)

If you don’t already have a text object in the game that’s going to be used to display the time, then now’s the time to make one.

Back in the script, you’ll also need to add the using UnityEngine.UI namespace in order to access user interface features, like Text objects.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

With that done, declare a public Text object, I’ve simply called mine timeText.

public Text timeText;

Finally, inside the Display Time function, set the text property of the Text object to using string.Format. Like this:

void DisplayTime(float timeToDisplay)
{
  float minutes = Mathf.FloorToInt(timeToDisplay / 60);  
  float seconds = Mathf.FloorToInt(timeToDisplay % 60);

  timeText.text = string.Format("{0:00}:{1:00}", minutes, seconds);
}

This method of formatting a text string may be new to you.┬áSo what’s actually happening here?

string.Format allows you to place variables inside of a formatted string, in this case taking the form of a time display, made up of two double-digit numbers that are separated by a colon (00:00).

Image showing how to use string.Format in Unity to format a time display.

Using string.Format makes it easy to display time in minutes and seconds.

Each of the two sets of curly brackets represents the minutes and seconds values of the time display. Inside the brackets, you will notice a single number to the left and ’00’ to the right, separated by another colon.

Don’t confuse these colons with the one that actually appears in the display. Instead, these are used to separate a reference number from the value’s format.

The value to the left of the colon decides which of the values will be used (the first ‘0’ being minutes and the second ‘1’ being seconds) while the value to the right of the colon decides how the value will be formatted. In both cases as a two-digit number.

Call the Display Time function

Lastly, remember to call the function when the timer is running, passing in timeReamining as a parameter:

DisplayTime(timeRemaining);

Because, to many of us, a digital time display is so familiar, it’s important to make sure that it’s presented in the right way.

Which brings me to my last tip, as there’s one aspect of a countdown timer’s display that you may not have thought about.

Advertisement

Time remaining vs time elapsed

It may surprise you, as it did me (because I had literally never thought about it until now), that a timer may often display differently depending on if time is being added or subtracted.

For example…

When displaying the amount of time elapsed, such as when using a digital stopwatch, the time will start at zero and each fully elapsed second will be displayed (often with milliseconds also visible). e.g. After one second has passed one second will show on the time display.

However…

In many examples of countdown timers, especially where milliseconds are not also displayed, a full second may be displayed even when there is less than a second remaining.

For example, during the entire final second of a countdown, one second will be displayed, with the timer immediately ending when it hits zero.

This is different from a stopwatch counting up where, during the first second of time, zero will be displayed.

This means that half a second of time is shown as one if counting down or zero if counting up.

You can see this behavior for yourself.

At the time of writing, the countdown timer built into Google behaves in exactly this way.

Google Countdown Timer

Notice how the last second displays one, even though the time remaining is less than one second.

And while not all timers use the same method, it is, arguably, the more familiar way to perceive time that’s counting down, particularly in games.

So how do you do it in Unity?

Luckily, because the calculation to display the time is inside a separate function from the actual time value, it’s easy to adjust the time value that’s passed in to display in this way.

Simply add a second to the time value before calculating the minutes and seconds display, like this:

void DisplayTime(float timeToDisplay)
{
  timeToDisplay += 1;

  float minutes = Mathf.FloorToInt(timeToDisplay / 60); 
  float seconds = Mathf.FloorToInt(timeToDisplay % 60);

  timeText.text = string.Format("{0:00}:{1:00}", minutes, seconds);
}

It’s worth mentioning that this only really works when displaying whole seconds.

If you choose to display milliseconds as well then, it’s better to display the time exactly as it is.

Time display with milliseconds included

Countdown timer made in Unity with a milliseconds display.

A countdown timer with a millisecond display.

To display time with a milliseconds value, create a third time value called milliseconds and use the modulo operation again.

This time, instead of 60 seconds use a divisor of 1 second and, this time, don’t use FloorToInt.

Then multiply the result by 1000 and add it into the text string, like this:

void DisplayTime(float timeToDisplay)
    {
        float minutes = Mathf.FloorToInt(timeToDisplay / 60); 
        float seconds = Mathf.FloorToInt(timeToDisplay % 60);
        float milliSeconds = (timeToDisplay % 1) * 1000;

        timeText.text = string.Format("{0:00}:{1:00}:{2:000}", minutes, seconds, milliSeconds);
    }

Unity countdown timer finished code example

Here’s how everything looks together in scripting.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class Timer : MonoBehaviour
{
    public float timeRemaining = 10;
    public bool timerIsRunning = false;
    public Text timeText;

    private void Start()
    {
        // Starts the timer automatically
        timerIsRunning = true;
    }

    void Update()
    {
        if (timerIsRunning)
        {
            if (timeRemaining > 0)
            {
                timeRemaining -= Time.deltaTime;
                DisplayTime(timeRemaining);
            }
            else
            {
                Debug.Log("Time has run out!");
                timeRemaining = 0;
                timerIsRunning = false;
            }
        }
    }

    void DisplayTime(float timeToDisplay)
    {
        timeToDisplay += 1;

        float minutes = Mathf.FloorToInt(timeToDisplay / 60); 
        float seconds = Mathf.FloorToInt(timeToDisplay % 60);

        timeText.text = string.Format("{0:00}:{1:00}", minutes, seconds);
    }
}

Save your work and return to Unity. In the inspector, don’t forget to hook up the timeText variable to the Text object you created.

Now it’s your turn

How are you using countdown timers in your project? What method did you use to display the time value in your game?

And did it work?

If not, what do you know now that you wish you’d have known at the time?

Whatever it is I want to hear it! Let me know, by leaving a comment below.

Font Attribution

DSEG digital font by Keshikan

by John Leonard French

Game audio professional and a keen amateur developer.

Popular Posts

Advertisement

Comments

  1. I followed all of the steps, and the timer displayed as promised, however, it didn’t actually count down. Any idea why?
    Thanks

    1. Author

      I double-checked the code example, just in case I’d made an error, but it works fine. Without looking at your script I’m not sure why it isn’t working for you but if you don’t mind sharing details of your project you can email me at [email protected] and I’ll take a look to see if you missed something.

Leave a Comment