We've discussed how coroutines can be a great tool to employ while making games in our article: Coroutines - A useful tool in every developer's toolbelt. Now we'll have a look at four ways in which a coroutine can be useful using code examples in the Unity game engine.

Using a coroutine as a timer

This was the example detailed in the article mentioned above. It consists of starting a coroutine, pausing execution for three seconds, and ending it with a Debug.Log statement that "prints" the output to the console. Essentially emulating a countdown timer or time delay.

C#
using System.Collections;
using UnityEngine;

public class ExampleCoroutine : MonoBehaviour
{
    IEnumerator WaitAndPrint()
    {
        yield return new WaitForSeconds(3);
        Debug.Log("Waited for three seconds!");
    }

    void Start()
    {
        StartCoroutine(WaitAndPrint());
    }
}

Using a coroutine for animation

In this example I created a coroutine to fade the opacity of an object (a 2D character sprite) through time until it gets completely transparent. The yield return null statement pauses the execution and resumes it in the following frame. This behaviour is similar to the Unity's Update() method, however a coroutine is more convenient because using Update() you would need to control the start and end of the fade with conditional checks as this method is always running.

C#
using System.Collections;
using UnityEngine;

public class ExampleCoroutine : MonoBehaviour
{
    IEnumerator Fade()
    {
        Renderer renderer = GetComponent<Renderer>();
        Color color = renderer.material.color;
        for (float alpha = 1f; alpha >= 0; alpha -= 0.01f)
        {
            color.a = alpha;
            renderer.material.color = color;
            yield return null;
        }
    }

    void Start()
    {
        StartCoroutine(Fade());
    }
}

Using a coroutine for a regular ocurring task

You can use a coroutine for a task that needs to occur on a time interval or for a task that could be executed less frequently than every frame for performance reasons, such as a function that checks for the current position of an enemy, for example.

Using the same game object as before, I changed the code to make the character sprite blink this time around. The new code makes the sprite repeatedly appear and disappear within a one second time interval.

Here's how this code works:

When entering play mode the Start() method is called initiating the ToggleVisibility() coroutine. The coroutine enters an infinite loop set by the statement while (true). Inside the while loop a conditional check toggles the renderer material alpha color channel between opaque and transparent. The execution stops for a second with the yield return new WaitForSeconds(1) statement and then resumes entering the next iteration of the while loop. Although this coroutine never stops due to the use of an infinite loop, it is nonetheless possible to end it. One way to do it would be to simply start and stop this coroutine using its name as a string argument, ex: StartCoroutine("ToggleVisibility") and StopCoroutine("ToggleVisibility").

C#
using System.Collections;
using UnityEngine;

public class ExampleCoroutine : MonoBehaviour
{
    IEnumerator ToggleVisibility()
    {
        Renderer renderer = GetComponent<Renderer>();
        Color color = renderer.material.color;
        float alpha = 0;
        while (true)
        {
            if (alpha == 1f)
                alpha = 0;
            else
                alpha = 1f;

            color.a = alpha;
            renderer.material.color = color;
            yield return new WaitForSeconds(1);
        }
    }

    void Start()
    {
        StartCoroutine(ToggleVisibility());
    }
}

Creating an animation chain using coroutines

In this example I trigger a new animation after the first one finishes, creating an animation sequence. Just like in the "Using a coroutine for animation" example above I used the opacity fade for both animations. You can, of course, sequence totally different kinds of animations and behaviours. Since I wanted to apply the same fade to the additional character sprite, I just adapted the coroutine to be run a second time.

C#
using System.Collections;
using UnityEngine;

public class ExampleCoroutine : MonoBehaviour
{
    public GameObject secondCharacter;
    Renderer currentRenderer;
    Renderer secondRenderer;
    bool faded = false;
    
    IEnumerator Fade(Renderer renderer)
    {
        Color color = renderer.material.color;
        for (float alpha = 1f; alpha >= 0; alpha -= 0.01f)
        {
            color.a = alpha;
            renderer.material.color = color;
            yield return null;
        }

        if (!faded)
        {
            faded = true;
            StartCoroutine(Fade(secondRenderer));
        }
    }

    void Start()
    {
        currentRenderer = GetComponent<Renderer>();
        secondRenderer = secondCharacter.GetComponent<Renderer>();
        StartCoroutine(Fade(currentRenderer));
        
    }

}

In the scene I've created a new game object containing another Sprite Renderer with a new sprite selected. Using the auto generated editor field I have set the reference to the newly created object.

Here's an explanation of the code above:

When entering play mode the Start() method is called setting references for each game object's Sprite Renderer. I made the fade coroutine receive the desired renderer to fade as an argument. The coroutine is started with the current game object renderer. After the fade completes, the coroutine is started again inside the conditional check, this time with the second renderer. I've put this conditional check here to prevent an unwanted infinite loop as without it the coroutine would continue to trigger itself with the second renderer over and over again.

Additional info

In the examples above to control the "yielding" stage of the coroutine, I used the return WaitForSeconds and the yield return null statements. The former yields after the defined number of seconds, the latter yields on every frame update.

There are more besides these two yielding options that can be useful when using coroutines to control physics, camera behaviours and more. Here are some that I think are important to know about:

WaitForSecondsRealtime - Suspends the coroutine execution for the given amount of seconds using unscaled time.

WaitForFixedUpdate - Waits until the next fixed frame rate update function.

WaitForEndOfFrame - Waits until the end of the frame after Unity has rendered every Camera and GUI, just before displaying the frame on screen.

Conclusion

We've gone over four ways in which you can make use of coroutines in your projects. I hope you found the examples useful and easy to understand. During the development of your projects and now armed with this knowledge you will probably find instances where coroutines could be the perfect solution for your specific problem.

Do you have any questions or want to share your thoughts with us? Let us know in the comments!

Jack Type
Blips founder, video game music composer & technical sound designer

As a child I never missed an opportunity to tear a toy with some electronics apart and use the parts to create something new. I ended up taking an electronics/programming course in my teens while also developing a deep passion for music. Owing much of this passion to a family owned night club and venturing briefly as a DJ, I embarked on a music production journey, and being an avid gamer triggered the desire to be involved in the creation of a game's music and sound. While continuing to grow both my technical and creative skillsets, I found that video game development fits me like a glove. It allows me to fully apply those skills for an endless number of possibilities.

Blips Game Music Packs

Note: You're leaving the Blips Blog. The visited links may be subject to different privacy and cookie policies.