Build a Reusable Timer in Unity to Control Explosions (and other fun stuff too…)

Jared Halpern
Apr 1, 2019 · 12 min read

What We’re Building

In this post, we’re going to learn how to build a Timer that does something when the time elapses. The mechanism to do something will be customizable and generic enough so that you can use it to programmatically execute basically anything you can script. In the example we build, we will script the explosion animation to appear and play when the time runs out. We’ll build this Timer as a standalone script which can be attached to any GameObject in Unity and reused. You’ll also learn a bit about Coroutines and Interfaces too.

What you need to already know

• Familiarity with C# variables, classes, methods, the Unity Editor, GameObjects, Prefabs

• How to add new scripts to GameObjects, work with the Inspector

• Creating new Animation States in an Animation Controller

If you’re shaky on any of these points, don’t worry. We’ll walk through each step and if something still isn’t clear, feel free to ask in the comments.

The end result will look like the below gif except the explosion will only go off once. The little pirate gnome is just hanging out and watching the explosion. It’s not part of this tutorial:

Before we get started, if you’re interested in reading more about making games with Unity, check out my book on Amazon: “Developing 2D Games with Unity”.

Let’s get started. Download the starter Unity project here. This project was built in 2018.3.8f1.

Ensure that MainScene is loaded and the Scene window is selected. If the MainScene isn’t loaded, find MainScene in the scenes folder and double-click it.

The scene should look like the below image.

Let’s talk about what we have in MainScene. Take a look at the Hierarchy Window on the left-hand side of the screen.

We have the standard Camera, set to 2D mode. We’re also starting with a TileMap containing the Background. Enemy and Explosion are prefabs that I’ve created for you ahead of time to save time. The Enemy prefab is pretty useless in this tutorial and is only there so you have something to look at while you wait for the timer to count down. Maybe the enemy is responsible for the explosion. I don’t know these things. Right. Now, moving along.

The Explosion prefab will eventually contain the functionality which is the focus of this tutorial.

Right-click in the scripts directory and create a C# script called “Timer”.

Double-click the Timer script to open it in Visual Studio. The boilerplate code inside Timer.cs will look like the below:

Delete the Update() method from the default code since we won’t be using it.

Add the following property to the top of the class, above the void Start() method:

This public variable will be used to set the countdown “wait time” in the Timer via the Inspector.

Create a new Coroutine called TimerCoroutine(). Since it’s a coroutine, make sure it has the return type: IEnumerator.

If you’re not familiar with Coroutines, here’s a brief description from the Unity documentation:

A coroutine is like a function that has the ability to pause execution and return control to Unity but then to continue where it left off on the following frame.

When calling a function, the function will run until completion within a single frame. This means that visual updates such as an animation will run entirely within a single frame. Running an entire method within a single frame might be what you want in some cases. But when running other types of actions such as counting down time in a Timer, you’ll want the method to continue running over the course of many frames.

Coroutines are used to perform actions that will span over a period of time longer than a single frame without blocking execution. The Coroutine class is a Unity Engine class and the IEnumerator Interface is part of the .NET runtime. When a C# class implements the IEnumerator interface, this means the underlying process can be stopped at a particular point for a specified amount of time. After a specified amount of time, control is then returned to that point in execution and the process resumes running. We’ll talk more about Interfaces in a bit.

This coroutine we’re writing will be used to keep track of time elapsed. Once the waitTime has elapsed, we’ll call a method to start the explosion animation. The secret sauce of our approach will be to kick off the animation in a generic way, so that this Timer script can be reused in the future on other objects and to do things other than start an animation.

Populate the TimerCoroutine() method as seen below. We’ll walk through this method and explain what it does.

• We’ve already explained how IEnumerator is required in the method signature for Coroutines.

• The variable elapsedTime will be used to track the elapsed time in the while-loop. With each iteration of the while-loop, we add the “delta” (the change) in time to elapsedTime.

• As we’ve described earlier, Coroutines allow a method execution to run over a period of time and over multiple frames. This is accomplished by yielding execution, then resuming execution in the next frame. The line: yield return null; is how we yield execution of our coroutine. There are other ways that a Coroutine can yield execution but this approach fits our requirements best.

• At the moment, when elapsedTime is greater than or equal to waitTime, our method exits the while-loop but nothing happens just yet.

In order to perform an action after the specified time elapses, we’re going to use an Interface. In C#, Interfaces allow you to define a group of methods (amongst other things) which a class can inherit from and implement. Once a class inherits from an Interface, it must implement all described methods in that Interface.

We’re going to write an interface called: IExecutableAction. Our Interface will contain a single method: ExecuteAction(). Classes in our Unity scripts can inherit from this Interface and implement ExecuteAction().

When the time elapses on our Timer object, we’ll write code to check the attached GameObject for any MonoBehaviours implementing IExecutableAction and call ExecuteAction() on them.

Let’s write this Interface. At the top of our Timer.cs script, add the following:

Note: The standard convention in naming Interfaces in C# is to preface the name with an “I”.

Now that we have an Interface, we need to put it to use. We’ll eventually be calling ExecuteAction() after exiting the while() loop in the TimerCoroutine, but don’t write that code just yet. There’s a few things we should go over first to make sure it’s clear what we’re doing.

Hit Save in Visual Studio to save our scripts and flip back to the Unity Editor.

Select the Explosion prefab from the Hierarchy Window on the left. Drag and drop the Timer script onto the Explosion prefab. You can drag the script into the Inspector right, or onto the object in the Hierarchy view on the left. Both will have the same effect.

With the Explosion prefab still selected, hit the Add Component button in the Inspector on the right. Select “New Script” to create a new C# script and call it “Explosion”. Unity might have created this script in the Assets directory. If it did, just move the script to the Scripts folder.

Double-click the Explosion script to open it in Visual Studio.

Delete the Update() method from the boilerplate code, then update the class to resemble the below.

Let’s go through this class.

• We’re inheriting from the Interface IExecutableAction which we defined in the Timer.cs script. This means we’ll have to implement void ExecuteAction() in this class.

• The property: Animator animator will store a reference to the Animator component in this Explosion GameObject.

• In the Start() method, retrieve the Animator component and store a reference.

• Implement ExecuteAction(), as required by the IExecutableAction Interface.

• Inside ExecuteAction(), we’re eventually going to do something. We’re saying “something” because we can basically do anything inside an implemented ExecuteAction() method. In this case, since we’re in the Explosion class, we’ll want to trigger the explosion animation.

• Before we fill in the ExecuteAction() method, we need to set up the Animation State transitions.

Hit Save in Visual Studio to save our scripts and flip back to the Unity Editor.

Hit Play in the Unity Editor and note how the Explosion plays in an infinite loop. This obviously isn’t what we want. We want the explosion to play a single time after the wait time has elapsed.

Select the Explosion prefab and click the Animator tab. If the Animator tab isn’t visible, go to Window -> Animation -> Animator to show it. The Unity Editor should look like the below.

Right click in the Animator window. Select Create State -> Empty to add a new State.

Select the new state and rename this state: “Waiting” via the Inspector.

We want the default State of this Explosion animation to be “Waiting”. In the Waiting State, the animation clip won’t be animating or even visible.

Select the Entry State and right click. Select “Set StateMachine Default State”

Connect the resulting arrow to the new Waiting State. The Waiting State will turn orange to indicate it’s the new default state and the Explosion clip won’t automatically begin playing. Your Animator should resemble the below image.

In fact, right now there’s no way to begin playing the Explosion clip, since there’s no state transition connecting to the Explosion State. We’re going to fix that shortly.

Right-click on Any State and select Make Transition. Connect the resulting transition to the Explosion State as seen below.

Then right-click the Explosion State, select Make Transition, and connect the resulting transition to the Waiting State. The Animator window should resemble the below.

Feel free to move around these animation states until they look neat and organized.

To control the transition from Explosion State to the Waiting State, we’re going to create a Trigger parameter. A Trigger parameter does what it sounds like: you “pull the trigger” by setting the parameter, and cause the state to transition.

In the Parameters section of the Animator window, select the “+” then select Trigger.

Rename the newly created Trigger, “explode”.

Select the transition from Any State to the Explosion State.

With the transition selected, look for the Transition Conditions in the Inspector.

Click the “+” sign in the lower right. Since “explode” is the only parameter, it will auto-populate in the Conditions.

Open up Visual Studio again.

We’re now going to set this trigger programmatically from the Explosion script. When the trigger is set, the Animator State will transition from whatever state it’s in (ie: Waiting, in this case) to the Explosion State. The Explosion animation clip is configured as part of the Explosion State, and will automatically play. After the Explosion clip plays through once, we’ve configured the Animator State Machine so that the State will transition to “Waiting”.

Open the Explode script and change the ExecuteAction() method to the below.

We’ve set the “explode” trigger that we configured moments ago. This will cause the Animator State to transition to the Explosion State.

That’s all the code we have to write for the Explode script.

Now open the Timer script.

Inside the Start() method, call StartCoroutine() as seen below. This is the syntax for calling Coroutines:

This will kick-off the TimerCoroutine() method we wrote earlier.

To refresh your memory, this is the TimerCoroutine() method we wrote earlier:

The problem with this method is that it doesn’t do anything once elapsedTime == waitTime. Let’s fix that.

At the top of the Timer class, underneath the waitTime property, add another property called monoBehaviours so it looks like the below:

This array of type MonoBehaviour will hold references to every attached MonoBehaviour on the GameObject the Timer script is attached to.

Inside the Start() method, use a call to GetComponents() to grab all attached MonoBehaviours on this GameObject. Update the Start() method to resemble the below.

• We’ve populated an array with all the MonoBehaviours attached to the same GameObject that the Timer script is attached to.

• One of these attached MonoBehaviours will eventually be the Explosion script.

• The plan is to loop through all of these MonoBehaviours and see which of them implement our IExecutableAction Interface. For every object we find that implements IExecutableAction, we’ll call ExecuteAction() on it.

• This means that we can attach multiple MonoBehaviours that implement IExecutableAction to this GameObject and the ExecuteAction() will be called for every single one of them once the Timer time elapses. We’re not going to utilize this aspect of our script in this tutorial, but it’s good to keep in mind.

Let’s put this array of MonoBehaviours to work.

Add a method underneath TimerCoroutine() called CheckExecutableActions() and fill it in as you see below.

This method loops through the array of MonoBehaviours and checks if each MonoBehaviour implements the IExecutableAction Interface. If we find an object that does implement this interface then call ExecuteAction() on it.

Last but not least, we need to call the CheckExecutableActions() method. Inside TimerCoroutine(), call CheckExecutableActions() after the while() loop exits, as seen below:

Save the Timer script and Explosion script then switch back to the Unity Editor.

Select the Explosion object in the Hierarchy view, drag and drop the Timer script onto the Explosion object to attach it.

With the Explosion object still selected, click the Overrides dropdown box, as seen in the below image. This will apply our changes to the Prefab itself instead of just this current instance.

The Timer Wait Time is set to 3 seconds, as you can see in the Inspector. Feel free to change this to whatever time you want.

Now we’re ready for action. Hit the play button.

You should see the explosion animation start after the Wait Time has elapsed.

This Timer object can be reused and added to any GameObject to create a time-based event. All you need to do is drag and drop the Timer script onto a GameObject, create a script on that object that inherits from IExecutableAction, and implement the ExecuteAction() method. Put whatever code you want to execute inside ExecuteAction() and it will be called when the Wait Time on the Timer script elapses.

Download the completed project here. The GitHub repo can be found here.

If you want to learn more about Unity or iOS Development, please feel free to follow me here on Medium, as well as Twitter.

I also wrote a book specifically focused on 2D game development called, “Developing 2D Games with Unity”, published by Apress and available via Amazon here. My website will also have updates on Unity development and iOS programming as well. Thanks for reading!

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch

Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore

Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store