Using Co-routines with Unity

Jaime
2 min readApr 27, 2021

--

Let’s say you want to implement a count down from 10 and when it reaches 0, you would like to display the message “Game Over!” on the screen. You would probably start creating code similar to this:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Countdown : MonoBehaviour
{
[SerializeField]
int _startNum;
// Start is called before the first frame update
void Start()
{
RunCountdown();
}
void RunCountdown()
{
int startNum = _startNum;
Debug.Log($"Starting countdown from {startNum}");
while (startNum >= 0)
{
Debug.Log(startNum);
startNum--;
}
Debug.Log("Game Over!");
}
}

After attaching this to a GameObject and setting to StartNum to 10 in the inspector, you immediately see a problem that the countdown runs as fast as it can! In this case, all iterations ran within a second.

Bug! The whole countdown ran within a second.

There must be a way to delay the next operation and this can be done inside a Coroutine. In a Coroutine, you can delay running commands with the yield statement. If you want to add a quick delay after a frame, you can run yield return null. If you want to delay the next operation in seconds, you can use yield return new WaitForSeconds(<float value>) instead.

To convert the RunCountdown function to a Coroutine, change the return type of the method to IEnumerator.

IEnumerator RunCountdown()

The next step is to introduce a delay with the yield keyword. In this case we will add the delay after deducting startNum by 1.

IEnumerator RunCountdown()
{
int startNum = _startNum;
Debug.Log($"Starting countdown from {startNum}");
while (startNum >= 0)
{
Debug.Log(startNum);
startNum--;
yield return new WaitForSeconds(1f);
}
Debug.Log("Game Over!");
}

To call the Coroutine, you can either call it as StartCoroutune(RunCountdown()); or StartCoroutine("RunCountdown");

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Countdown : MonoBehaviour
{
[SerializeField]
int _startNum;
// Start is called before the first frame update
void Start()
{
StartCoroutine(RunCountdown());
}
IEnumerator RunCountdown()
{
int startNum = _startNum;
Debug.Log($"Starting countdown from {startNum}");
while (startNum >= 0)
{
Debug.Log(startNum);
startNum--;
yield return new WaitForSeconds(1f);
}
Debug.Log("Game Over!");
}
}

After making this change, we can now see that the countdown interval is delayed by 1 second.

Based on the timestamps, the delay interval is 1 second

--

--

Jaime
Jaime

No responses yet