Coroutines

When working in Unity and you find yourself asking the following questions:
- How can I make sure task A finishes before I do task B?
- How do I delay a method by X seconds?
- How can I wait for a condition to be met before continuing?
- How can I wait for a response from a web request?
- How do I prevent locking up the main thread while performing a computationally-intensive operation?
This is where Coroutines can help!
What are Coroutines?
Unlike normal C# functions, which are executed to completion within a single frame, Coroutines can:
- Pause execution (
yield) and return control to Unity - Continue execution in the next frame
Syntax
- A Coroutine must return
IEnumerator - Within the body, you must have a
yieldstatement - To start a Coroutine:
StartCoroutine(COROUTINE_FUNCTION())orStartCoroutine("NAME_OF_COROUTINE")
How do you use Coroutines?
How to wait for X seconds
private void Start()
{
StartCoroutine(TaskA(3));
}
private IEnumerator TaskA(int delay)
{
Debug.Log("Task A started!");
yield return new WaitForSeconds(delay);
Debug.Log("Task A finished after " + delay + "seconds");
}
private void TaskB()
{
Debug.Log("Task B!");
}
Result:

How to run a computationally-intensive operation without locking up the main thread
private int _counter = 0;
private void Start()
{
StartCoroutine(LongRunningTask());
}
void Update()
{
if(_counter < 20)
{
Debug.Log("_counter: " + _counter);
}
}
private IEnumerator LongRunningTask()
{
// simulate a long running task
while(_counter < 20)
{
_counter++;
// return execution to main thread and
// continue from here next frame
yield return null;
}
}
Result:
- You’ll notice that 1 is printed twice. That’s because:
Startis called just before the first timeUpdateis called- When
Updateis called, any previouslyyield-ed Coroutines are processed afterwards


Wait until a condition is met
private IEnumerator WaitUntilCounterIs(int value)
{
yield return new WaitUntil(() => _counter == value);
Debug.Log("Counter is now at: "+ value);
}
Result:
- The
Debug.Logwill only be called once_counterequalsvalue - The above would have the same performance as running
while(_counter != value)
Considerations
- Coroutines do not run on separate threads — they run on the main thread
- You can stop a Coroutine using
StopCoroutine(nameOfCoroutine/reference) - Where possible, you can use C# Tasks for asynchronous functionality