When developing games, we often need to do tasks that span over several frames. In Unity, however, everything in a function is generally processed on the same frame. Hence, to do tasks sequentially over several frames, we use coroutines. A coroutine can be used to execute a piece of code across multiple frames.
To understand the difference between regular functions and coroutines in Unity, let us look at the following slides:
In the slides above, we see that in the execution of normal functions, the entire function is executed per frame. However, in the execution of coroutines, The same function will be executed over different frames.
We use a coroutine when we need to perform a task that will be carried out over several frames. For example, we can use a coroutine if we need to write code for a timer that will be executed frame by frame. A coroutine in C# has a return type of IEnumerator
and must have a yield command. Look at this timer example and see how we start a coroutine.
Let's look at the following code to start a coroutine:
using System;using System.Collections;class TimerCoroutine{//main functionstatic void Main(){//manually handling coroutine since this is a regular C# script, not a Unity scriptTimerCoroutine timerCoroutine = new TimerCoroutine();timerCoroutine.StartTimer();//code in Unity to call coroutine//StartCoroutine(Timer());}//coroutine functionIEnumerator Timer(float timer_stop = 5.0f){int timer = 0;//loop for timerwhile (timer < timer_stop){timer += 1;System.Console.WriteLine("Timer = " + timer);//yeild statement to continue execution in next frameyield return null;}}//method to manually enumerate coroutine in C# scriptvoid StartTimer(){IEnumerator coroutine = Timer();while (coroutine.MoveNext()) { }}}
Let’s look at what the code above does in a bit of detail:
Lines 7–14: This is our main function. We manually create our class object and then start the coroutine. This is done because this is a regular C# script, not a Unity script. In Unity, we can simply start by using the StartCoroutine()
function.
Lines 16–26: This is a coroutine that updates our timer frame by frame instead of doing it in one single frame. It has an IEnumerator
return type with a yield return null
command inside the loop that we have for our timer. After running the yield return null
command, the coroutine will exit the function and will continue its execution from this point when it is called again.
Note: In Unity, we can use
Time.deltaTime
to correctly represent our frames with seconds. To read up on it, visit "What is "Time.deltaTime" in Unity?".
Lines 29–33: This function was created to manually call our coroutine as this is a regular C# script, which is not running on the Unity Engine. In Unity, we would not need to write this script.
In order to stop a coroutine, we can primarily take two courses of action:
Destroy or disable the object that calls the coroutine.
Stop the coroutine using the StopCoroutine()
function or the StopAllCoroutines()
function.
Coroutines are very useful in game development. Whether it's smooth transitions between scenes or fading textures from materials, they are powerful tools for performing tasks sequentially.