How to make a countdown timer in Unity

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

In Scripting Basics by John FrenchUpdated 83 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)

I recently made a video of this article, which shows you everything you need to know about making a Countdown Timer in Unity.

Or, you can continue below for the full written article instead.

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 for creating 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.

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?

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.

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.

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.

Ready-made options

While a countdown timer can be a very simple mechanic, as is the example in this article, it’s also a very important one.

And, if it’s going to form a major part of your game – for example: if you’re constantly resetting or restarting the timer, if you need to add multiple timers to a scene or if you need advanced functionality (like saving the remaining time value between sessions) it might make a lot of sense to use a premium timer asset. 

Such as Timers & Clocks (Unity Asset Store) by TurnTheGameOn, which provides a ton of advanced features and easy to use prefabs, saving you time and effort.

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

John French profile picture

by John French

Game audio professional and a keen amateur developer.

Get Game Development Tips, Straight to Your inbox

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

How this content was created

This article was written using first-hand research and experience, without the use of AI. For more information on how Game Dev Beginner articles are written, see my writing policy.

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.

          1. Thank you so much for the clarification. You are a real lifesaver! But do you have any idea why TextMeshPro doesn’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

    1. use the following script:

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

      public class Timer : MonoBehaviour
      {
      public Text timeText;

      public float timeToDisplay = 0f;

      private void Start()
      {
      timeText = GetComponent();
      }

      void Update()
      {
      DisplayTime();
      }

      void DisplayTime()
      {
      timeToDisplay += Time.deltaTime;

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

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

  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);
      1. Thanks for the reply! I’ve tested and it still doesn’t count down in real-time…

        It displays hours/mins/seconds but when the seconds are being deducted it isn’t going down in real-time if you were to test you’d see.

        Thanks for the help anyway!

  14. Hey, I want to restart the timer once it reaches 0, to give a bit more context, I want this timer to reset, because the main camera’s x speed will increase, I got those down, but I want the timer to reset so then once the timer is set off again, it will once again increase the speed

    1. Author

      The simplest way to do this would be to add more time in the if/else that checks to see if it’s finished (so instead of setting it to 0, set it to the restarted value. And to also not set timerRunning to false if you want it to restart right away.

  15. Thanks for this. My comment is not about this article. Can you help me finding out how to spawn an asset at random positions by pressing a key in unity 3d. And please reply fast. Cause I want the reply before 8th jan 2021. By the Way, love your article

    1. Author

      Thanks! Which part are you struggling with so far? the random position, the instantiate function (or object pooling, if you’re doing that) or the input trigger?

  16. now i want to add a text with game over when the timer is on 0:00 what do i have to do?

  17. tnx!
    i want to add a text with game over when the timer is on 0:00 can you help me with this?

    1. Author

      Replace the Debug.Log placeholder line – Debug.Log(“Time has run out!”); – with whatever code you want to use to show the message. Easiest way would be to set up the game over message as you want and then enable it from this line.

  18. I get this error what does it mean: FormatException: Index (zero based) must be greater than or equal to zero and less than the size of the argument list.
    System.Text.StringBuilder.AppendFormatHelper (System.IFormatProvider provider, System.String format, System.ParamsArray args) (at :0)
    System.String.FormatHelper (System.IFormatProvider provider, System.String format, System.ParamsArray args) (at :0)
    System.String.Format (System.String format, System.Object arg0, System.Object arg1) (at :0)
    timer.DisplayTime (System.Single timeToDisplay) (at Assets/Scripts/timer.cs:43)
    timer.Update () (at Assets/Scripts/timer.cs:25)

    1. Author

      My guess, from the look of it, is that you’re trying to pass in too many variables to the String.Format function. Double check that line for errors.

  19. Works like a charm! Works very well, and very easy to follow! Usually, when searching up for Unity Tutorials, all of them are really hard. This is the easiest tutorial I ever followed and worked perfectly! Thanks

  20. Hi John, this solution works great and was very simple to follow. Was just wondering how you would be able to stop the timer from resetting after a scene change, since the game I’m creating requires that. Thanks!

    1. Author

      Hi Hannah, lots of ways you could do this. Some that I can think of involve using Don’t Destroy on Load to keep the same timer object across both scenes, or alternatively, storing the last time and loading it in the next Scene, which might be a bit cleaner. Check my page on How to Load a Scene in Unity for more on that option.

    2. You should be able to do it by making the variable static so do this:

      static public float timeRemaining = 10;

  21. Thank you John, this works so much better than the previous script I was using and solved a lot of problems for me. Appreciate it!

  22. If I want to time each level and display the time, what do I do?

    1. Author

      Lots of ways to do this, but one simple way would be to have a timer object, which adds time every frame:

      float timer=0; 
      
      void Update(){
      timer += Time.deltaTime; 
      }

      and then display that value using the formatting method in the post.

  23. Thank you! Easy to follow, great article. I was able to implement it in my code, no problem.

  24. Fantastic stuff. Works like a charm. A question though, is there a way to pause the time without setting timescale to 0? like in the case of a pause menu.

    1. Author

      One way to do that would be with a boolean and then just check if it’s false when subtracting time:

      
      public class Timer : MonoBehaviour
      {
          public float timeRemaining = 10;
          public bool gamePaused;
      
          void Update()
          {
              if (timeRemaining > 0 && !gamePaused)
              {
                  timeRemaining -= Time.deltaTime;
              }
          }
      }
      
  25. Hey John, followed your tutorial and got a working timer settled but I have a question. I have an audio que play every second after counting down 10 and because it is using update, it frequently plays the audio for every frame, is there a way to set the audio apart from the update but still reads from the text display? Thank you for the tutorial.

    1. Author

      There are lots of ways you could do it, generally speaking, you just need to be able to check when a whole number has changed as the raw time value will change constantly since it’s a float. One way could be to round the seconds value down to an Int using FloorToInt and store it in a whole seconds variable, then you could check if it has changed between frames. You’ll be better off storing this as another variable, instead of trying to read the text.

  26. Thank You, John!
    That was very educational; and helpful!

    I used this to add a timer for an English spelling game I made for my elementary school students, here in Japan.

    Cheers!

  27. This is an incredibly well written article.

    It’s as close to perfect as it can get.

    Maybe even it is perfect…

    Anyway, I’m pumped I found your website. Going to literally read everything you’ve made.

  28. Hi John. Great content, as always. Your website has become one of my favourite Unity resources.

    I’ve followed along with your countdown timer tutorial, but am having an issue when trying to display the timer with milliseconds. Basically, when set to milliseconds, the countdown timer counts down to 0 correctly, but then stops at -01:-01:-026 (instead of exactly at 0). Any idea how to prevent that?

    Thanks again

    1. Author

      Thanks! Locking the timer to zero when it runs out should fix this, since the timer will always overshoot by a little bit. There is a section on this in the article if that helps, but I realise now that I may not have included it in the other examples. Let me know if it was something else.

    1. Author

      As far as I know, that’s not possible. The only way to do something like that would be to save the time and date when the game closes and compare it when the game is next opened.

  29. I’m trying to reset the timer after a set amount of seconds, but i can’t get it work.

    1. Author

      Hi, you should be able to do this by simply checking the time elapsed or time remaining value with an if statement. If it’s not working, chances are there’s a typo or a simple error. If you’re happy to send me the script (to [email protected]), I could check it for you.

  30. How do you detect if the time remaining is 5 seconds left to notify the user?

    1. Author
      if(!userNotified && timeRemaining < 5)
      {
          // Notify user
          userNotified = true;
      }
      

      It’s a simple method, but something like that should work.

Leave a Comment