Unity C#: Beautiful Coroutines
There are some actions which takes time as a primary factor. There are actions that are needed to performed over time, or there are functions that are needed to be performed on the background while a particular function is running. Consider the following code in the Update function in the MonoBehaviour of the Unity Script.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Timer : MonoBehaviour {
private float timeLeft = 20.0f;
// Use this for initialization
void Update () {
timeLeft -= Time.deltaTime;
if (timeLeft < 0)
{
TickTickBoom();
}
Debug.Log("Time Left: " + timeLeft);
}
void TickTickBoom()
{
Debug.Log("KABOOM");
}
}
Now if you add the timer script to an empty gameobject and run the game. You will see a lot of messages displaying Time left and it is happening every single frame. Later when the timeLeft hits zero, it will invoke the TickTickBoom function. For a small application it really does not matter but if you are building a game or a very large application, such update function will kill a lot of processing power. Normally it is always advisable to avoid as much lines as possible in the update function just to optimize the application performance. Why not refactor this into something like below:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Timer : MonoBehaviour {
private float timeLeft = 20.0f;
void Start()
{
StartCoroutine(TimeBomb());
Debug.Log("Timer started");
}
IEnumerator TimeBomb()
{
while(timeLeft > 0)
{
Debug.Log("Time Left: " + timeLeft);
yield return new WaitForSeconds(1.0f);
timeLeft--;
}
TickTickBoom();
}
void TickTickBoom()
{
Debug.Log("KABOOM");
}
}
If you run this now, you will see the message is coming every second. You will also notice that unlike the KABOOM is displayed continuously in the previous code, here the message is shown only once. It is because the a particular method TimeBomb is executed only once whereas Update is run every frame. Also in our second code we do not have an update function. The magic lies in the IEnumerator function that we made. This is called coroutines in C#. Inside the TimeBomb coroutine, we are applying yield return WaitForSeconds with an argument 1.0f. Basically what it does is that it waits for 1 second before it moves to the next line and the whole code is working in a while loop it will keep on looping until timeLeft reaches zero. As yield is creating 1 second delay, the whole loop has become a sort of timer. When it finishes its loop it will invoke TickTickBoom method. This TimeBomb is invoked right at the start method and so it will happen only once. You will also notice that after TimeBomb is invoked, the Start method will not wait and move to the next Debug line which says Timer Started. It means that the Start method has invoked the TimeBomb function and that TimeBomb function runs on background while the Start method continues finishing its code block. This is very important for developers who applies different validation checks that are needed to be checked from time to time. Since Coroutines deals with time, it is widely used to create scripts for animations, since animation deals with time. As Coroutines run along with the function (Update or any other function methods), developers can create IEnumerator functions to check large data, maybe like 100000 of them. Imagine having a loop, with multiple lines and having 100000 iterations on a single frame void function. The application will hang while running. So next time if you think there are functions that you need to make that deals with time and that you think will run on background while other processes are taking places, always take full use of Coroutines.
“Since coroutines run on background”
They don’t, coroutines run along with the Update event… just a small correction. 🙂
Also it’s always recommended to keep track of your coroutine and save a reference in a variable so you can manipulate them.
Thanks YoyoMario for the correction. I have updated it accordingly.
Also thanks for the suggestion of using variables to track coroutines. This is something I have started to use recently.
No worries Koshai.
We are all here to exchange and learn, nobody knows everything!