Version: Unity 6.1 (6000.1)
Language : English
Split tasks across frames with coroutines
Analyzing coroutines

Write and run coroutines

A coroutine is a method that can suspend execution and resume at a later time. In Unity applications, this means coroutines can start running in one frame and then resume in another, allowing you to spread tasks across several frames.

Regular, non-coroutine methods run to completion before returning control to the caller, which in the Unity runtime means their action completes within a single frame update. In situations where you want the work of a method to take effect over several frames, such as a gradual fade-out effect, you can use a coroutine. Coroutines are also useful for handling long asynchronous operations, such as waiting for HTTP transfers, asset loads, or file I/O to complete.

Important: Don’t confuse coroutines with threads. Synchronous operations that run within a coroutine still execute on the main thread. If you want to reduce the amount of CPU time spent on the main thread, it’s just as important to avoid blocking operations in coroutines as in any other script code. If you want to use multi-threaded code in Unity, your options are:

Writing coroutines

Consider the task of gradually reducing an object’s alpha (opacity) value until it becomes invisible. For the fading effect to be visible, the opacity must reduce over a sequence of frames. If you tried to write a Fade method, you might write something like the following:

void Fade()
{
    Color c = renderer.material.color;
    for (float alpha = 1f; alpha >= 0; alpha -= 0.1f)
    {
        c.a = alpha;
        renderer.material.color = c;
    }
}

This method is not a coroutine, so it executes every iteration of its for loop within a single frame update and the object disappears instantly instead of appearing to fade out. One posible solution is to add code to the Update function that executes the fade on a frame-by-frame basis. However, it can be more convenient to use a coroutine.

Coroutines are methods with an IEnumerator return type and a yield return statement included somewhere in the body. The yield return statement is the point at which execution is suspended. The previous Fade method can be rewritten as a coroutine as follows:

IEnumerator Fade()
{
    Color c = renderer.material.color;
    for (float alpha = 1f; alpha >= 0; alpha -= 0.1f)
    {
        c.a = alpha;
        renderer.material.color = c;
        yield return null;
    }
}

This version of the method executes one iteration of its for loop before suspending execution at the yield return null statement. It resumes and executes another iteration of the loop in the next frame, and so on, making the gradual fade effect visible. The loop counter in the Fade method maintains its correct value over the lifetime of the coroutine, and any variable or parameter is preserved between yield statements.

Starting and stopping coroutines

To set a coroutine running, use the StartCoroutine method:

void Update()
{
    if (Input.GetKeyDown("f"))
    {
        StartCoroutine(Fade());
    }
}

To stop a coroutine, use StopCoroutine and StopAllCoroutines. A coroutine also stops if:

  • The value of GameObject.activeSelf becomes false for the GameObjectThe fundamental object in Unity scenes, which can represent characters, props, scenery, cameras, waypoints, and more. A GameObject’s functionality is defined by the Components attached to it. More info
    See in Glossary
    the script is attached to.
  • The MonoBehaviour script is destroyed with a call to Destroy.

Note: Disabling the MonoBehaviour script by setting enabled to false doesn’t stop coroutines.

Resuming coroutines

When a suspended coroutine resumes execution depends on the yield instruction provided in the yield return statement. A yield return null resumes on the next frame. Unity has a set of custom yield instructions that you can use to resume after a specified time, when a specified conditions is met, or at specific points in the Player loop. For more information, refer to Yield instruction reference.

In the case of fade effect example, you might want the fade effect to happen at a lower and more consistent rate than the frame rate. You can yield return the WaitForSeconds instruction to introduce a fixed time delay between iterations of the Fade method as follows:

IEnumerator Fade()
{
    Color c = renderer.material.color;
    for (float alpha = 1f; alpha >= 0; alpha -= 0.1f)
    {
        c.a = alpha;
        renderer.material.color = c;
        // Wait for 0.1 seconds before the next iteration
        yield return new WaitForSeconds(.1f);
    }
}

Coroutines in Edit mode

Coroutines are primarily a runtime feature. The associated runtime yield instructions are in the UnityEngine namespace and run in the Editor’s Play mode or in a standalone platform Player. They can also run in Edit mode if your scriptsA piece of code that allows you to create your own Components, trigger game events, modify Component properties over time and respond to user input in any way you like. More info
See in Glossary
use the [ExecuteInEditMode] or [ExecuteAlways] attributes, but the update loop in Edit mode is not as fixed and regular as the Player loop.

For coroutines designed specifically to run in Edit mode, use the Editor coroutines package.

Coroutines in tests

Unity Test Framework Play mode tests marked with the [UnityTest] attribute run as coroutines and allow you to yield custom instructions for the Unity Editor from tests. For more information, refer to Yield instructions for the Editor.

Additional resources

Split tasks across frames with coroutines
Analyzing coroutines