Coroutines in Unity are like little timers you can set for your code. But rather than blocking your mainline of code while your timer sits and waits, Unity peels it off to the side and comes back to it when needed. Coroutines also provide a way to spread actions over multiple frames. Keep in mind, code in the Update function runs every frame. It runs ALL the code in the Update statement every frame. So, if you wish to loop through a series of actions, you cannot just create a loop to execute them within the Update method. This is because the entire loop will execute in a single frame (remember, there are 60 of those every second). In fact, it will happen so fast you won’t even see the intermediate steps. Just the first and the last. You can however put that same loop or series of instructions in a coroutine and spread the action out over multiple frames.
We can illustrate with a simple bit of partial code. For the most part, you won’t even need a fully working example to understand how the process works.
The coroutine is declared with a return type of IEnumerator
and is invoked with the StartCoroutine()
method. The key is the yield return
statement. In the example below, the DoSomethingOccasionally()
method is invoked when the DoSomething()
class is instantiated. Code Block 0 will be executed immediately. However, the yield return
statement will cause the execution to leap out of method call and carry on. When the next frame is executed, the code jumps back into the DoSomethingOccasionally()
method but instead of executing from the beginning, it picks up from where it left off. Namely, Code Block 1. You can in fact, have an entire sequence of these with each block getting executed on a subsequent frame.
using System.Collections;
using UnityEngine;
public class DoSomething: MonoBehaviour
{
void Start()
{
StartCoroutine(SpawnRoutine());
}
IEnumerator DoSomethingOccasionally ()
{
// code block 0
yield return null;
// code block 1
}
}
Now, you might not want to execute on every frame. So, Unity gives us another trick, the WaitForSeconds()
class. Instead of returning a null (or any other value) we can return a WaitForSeconds()
object. This causes a delay between code blocks based on seconds rather than frames.
using System.Collections;
using UnityEngine;
public class DoSomething: MonoBehaviour
{
void Start()
{
StartCoroutine(SpawnRoutine());
}
IEnumerator DoSomethingOccasionally ()
{
// code block 0
yield return new WaitForSeconds(5f);
// code block 1
}
}
Finally, we might want to do something endlessly, like spawn enemies, or raise taxes. To do this, we can place the yield return
statement within a loop. The code below will execute the same as the above code, but instead of executing once, it will alternate between Code Block 0 and Code Block 1 until the game object is destroyed.
using System.Collections;
using UnityEngine;
public class DoSomething: MonoBehaviour
{
void Start()
{
StartCoroutine(SpawnRoutine());
}
IEnumerator DoSomethingOccasionally ()
{
while (true)
{
// code block 0
yield return new WaitForSeconds(5f);
// code block 1
}
}
}
It should be noted, the way the code above is written, Code Block 1 will be executed one less time than Code Block 0. This is because on the first loop iteration, Code Block 0 is executed and then we jump out of the loop. After 5 seconds, we return to where we left off, execute Code Block 1 which ends the first loop iteration and immediately starts the next loop iteration by executing Code Block 0 before it again, exits and waits 5 seconds. If we want the code blocks to truly alternate, one at a time, we will need a second yield return
statement following Code Block 1.
Additionally, if there was any code just after the while loop, it will never get executed at all, since our coroutine will remain in the loop until object destruction.
As always, there are endless ways to complicate and exploit this feature, but these basics should get you started.