Coroutines in Unity: Part 1 – Basics

Coroutines in Unity: Part 1 – Basics

As per Unity docs, a coroutine is a function that can suspend its execution (yield) until the given YieldInstruction finishes. In other words, coroutines in Unity work like normal functions till they encounter a YieldInstruction. At this point, the coroutine is paused and the control returns to the function which called the coroutine in the first place. Further, the coroutine continues its execution normally after the yield condition is met.

Using the Coroutines in Unity

A coroutine is a function which has a return type of IEnumerator and it includes a yield return statement somewhere in the body. To set a coroutine running, you need to use the StartCoroutine function.

The yield return null line pauses the execution and is resumed in the following frame. 

Here is an example of a coroutine that counts down the timer from 60 to 0.

    void Start()
    {
        StartCoroutine("Timer");
    }

    public int timer = 60;
    public IEnumerator Timer()
    {
        while (timer > 0)
        {
            yield return new WaitForSeconds(1);
            timer--;
        }
        Debug.Log("Game Over");
        yield return null;
    }

There are other ways of using the StartCoroutine function:

StartCoroutine(Timer());

or

 IEnumerator coroutine = Timer();
 StartCoroutine(coroutine);

Note: StartCoroutine is a public method of the MonoBehaviour. Thus, you need a MonoBehaviour class or an object of MonoBehaviour to call a coroutine.

Benefits of Coroutines over update

Coroutines can be used as a way to spread an effect over a period of time, but it is also a useful optimization. We mostly use the Update function to perform periodic tasks. However, this function is called many times per second. You can use a coroutine when you do not need periodic task to repeat every frame. An example of this might be an alarm that warns the player if an enemy is nearby. The code might look something like this:

    bool ProximityCheck()
    {
        for (int i = 0; i < enemies.Length; i++)
        {
            if(Vector3.Distance(transform.position,enemies[i].transform.position) < dangerDistance)
            {
                return true;
            }
        }
        return false;
    }

If there are a lot of enemies then calling this function every frame might introduce a significant overhead. However, you could use a coroutine to call it every tenth of a second:

    IEnumerator DoCheck()
    {
        while(true)
        {
            if(ProximityCheck()){
                //run... the enemy is near!
            }
            yield return new WaitForSeconds(.1f);
        }
    }

This would greatly reduce the number of checks carried out without any noticeable effect on gameplay.

Stopping a coroutine

You can stop a coroutine with StopCoroutine and StopAllCoroutines

StopCoroutine has three function overloads:

A string function naming the active coroutine

Use this to stop the coroutine which initially started with a string.

StopCoroutine(“Timer”);

The IEnumerator variable used earlier to create the coroutine.

Use this to stop the coroutine which started with IEnumerator as above. 

StopCoroutine(coroutine);

The Coroutine to stop the manually created Coroutine.

Use StopCoroutine with the Coroutine used for creation.

i.e., if you have started a coroutine as below: 

Coroutine f1 = StartCoroutine(Timer());

you can stop coroutine using

StopCoroutine(f1);

Note: Using StopCoroutine(Timer()); will not stop the coroutine.

Yield Instructions that can be used

WaitForEndOfFrameWaits until the end of the frame after Unity has rendererd every Camera and GUI, just before displaying the frame on screen.
WaitForFixedUpdateWaits until next fixed frame rate update function.
WaitForSecondsSuspends the coroutine execution for the given amount of seconds using scaled time.
WaitForSecondsRealtimeSuspends the coroutine execution for the given amount of seconds using unscaled time.
WaitUntilSuspends the coroutine execution until the supplied delegate evaluates to true.
WaitWhileSuspends the coroutine execution until the supplied delegate evaluates to false.

We will learn some interesting facts about Coroutines in the next part.

Happy Coding!

Share This Post

Post Comment