How to make a countdown timer in Unity

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

In Unity by John36 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.

Get Helpful Game Development Tips, Straight to Your inbox

Get access to exclusive tips & tricks and master game development basics the easy way, with deep-dive tutorials and guides.

Popular Posts

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.

  2. Thanks for this easy-to-follow demonstration. I’ve created a base project, with an hours field as well. I plan to use this on multiple projects, including just a basic, user-settable timer.

  3. hi john thanx for your great sharing but in my case it does not follow the seconds. Time is too slow . I added “*10” to make it as faster as seconds. I guess update () time period cause this. Could you please help me ?

    1. Author

      I don’t know your project, but it sounds like something else is possibly happening here. Try copying the code example in the post into a blank Scene and see if it works as you expect it to. If it does, then something else is causing the issue or there’s an error. Let me know how you get on.

  4. So I followed this little guide to the letter, and while the timer itself is functional, it vomits out a deluge of errors all saying “NullReferenceException: Object reference not set to an instance of an object”, and the line causing it seemingly involves the “timeText.text = string.Format(“{0:00}:{1:00}”, minutes, seconds);” part.

    What’s up with that?

    1. Author

      Sounds like you don’t have a reference to the Text object (timeText), so every time it tries to update, you’re getting a null reference error. Double-check that the Text object you want to use to display the countdown is actually connected in the inspector.

      1. John, I do but it still won’t work. I double-checked, triple-checked, and quadruple-checked. I am sure that I have the Text GameObject that I want connected, but it still wont work

        1. I had this error, but I figured it out, so are you sure you’re not just adding the script to the text? You can’t just add it as a component, you need to add it to something else and then drag the text object into the slot. Also, it could be that you’re using a TextMeshPro text object because they don’t work with this script.

  5. The Code Is Really HelpFul But In My Ui It Does Not Do Anything To The Text
    I double Checked and the Text Is In The Inspector But Does not Work

    1. Author

      Interesting. There must be something else going on then. Would you be willing to share more details about your project so that I can find out what’s wrong. Then I can update the article. Email me at [email protected] if you’d be able to help.

  6. Loved the explanation on the countdown concept, didn’t think of it in the way that you described it. Thanks 🙂

  7. You can use this for the DispalyTime method and then you don’t have to worry about maths and stuff.

    void DisplayTime(float timeToDisplay)
    {
    TimeSpan remaining = TimeSpan.FromSeconds(timeToDisplay);
    timeText.text = remaining.ToString(@”hh\:mm\:ss”);
    }

  8. How do I make a UI for the timer? I’m fairly new to coding, so what would the steps be?

    1. Hi Hunter! You would start off by creating a Text element in the project Hierarchy. Then add the script to the text and assign it. You can search in google for videos too.

    1. Author

      If you’re looking to store the progress of the timer, but not keep it running, probably PlayerPrefs or a similar save file system. If you want the Countdown to have continued I’m assuming you’re going to have to also check the system time on exit and update the timer when the application is running again. This isn’t something I’ve tried personally, This forum post may help.

  9. How can i start from 0:00 instead of setting a time and counting it down to 0:00

  10. Thank you for your instructions.

    It helps me a lot.

    Thumbs up from Taiwan.

  11. Great script! I now have a constantly running and resetting 15 second timer displayed on screen. I want to use it to trigger an event on every player prefab in the game that is spawned in during runtime every time the timer hits 0. What is the best practice way to sync the animation/movement of several objects in the scene to the beat of the timer?

    Do I grab a copy of the timer script on every instantiated player when they spawn, and then each player has their own timer? would they all be on the same timer or out of phase depending on when they were instantiated?

    or can I somehow use the timer script to get a reference of each object i want to move and run it from that script?

    1. Author

      You’d probably be better to keep a single time source that calls an event and then have other objects subscribe to it.

  12. Hey John thank you for this snippet of knowledge I appreciate this.

    So here is my problem, how I solved it, and what this will be used for. I thought I’d share since you asked.

    Here is my working timer code using Coroutines:

    private IEnumerator Round(int time)
    {
    while (time >= 0)
    {
    timer.text = “Timer: ” + time–;
    yield return new WaitForSeconds(1);
    }
    Debug.Log(“Time Over”);
    gis = false;
    foreach (GameObject court in spawnCourt)
    {
    court.SetActive(false);
    }
    }

    So no problems there but what I want to do is add more time while time is running out. Now I’m like should I stop coroutine start a new one??? So instead of failing a bunch I went to search the good ole web. I found your solution and I’m like i can totally just add more time without stopping and starting coroutines or any other way of doing it so yeah thanks.

    Here is a link to my game I will be updating it soon I’m just working on the game modes right now.

    https://sidequestvr.com/app/1330/bring-the-heat

  13. How would you get this to work trying to set to 24 hours (or even higher)

    Really appreciative of the great tutorial, I noticed Kovacs’s reply and tried that to which it helped a little but when setting it to 24h or even 10h / 8h it didn’t go down in real time…

    1. Author

      I haven’t tried this so this is off the top of my head, but you could try something like this to get hours…

      using the same seconds value for the time:

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

Leave a Comment