unity3d Coroutines Chaining coroutines


Example

Coroutines can yield inside themselves, and wait for other coroutines.

So, you can chain sequences - "one after the other".

This is very easy, and is a basic, core, technique in Unity.

It's absolutely natural in games that certain things have to happen "in order". Almost every "round" of a game starts with a certain series of events happening, over a space of time, in some order. Here's how you might start a car race game:

IEnumerator BeginRace()
{
  yield return StartCoroutine(PrepareRace());
  yield return StartCoroutine(Countdown());
  yield return StartCoroutine(StartRace());
}

So, when you call BeginRace ...

 StartCoroutine(BeginRace());

It will run your "prepare race" routine. (Perhaps, flashing some lights and running some crowd noise, resetting scores and so on.) When that is finished, it will run your "countdown" sequence, where you would animate perhaps a countdown on the UI. When that is finished, it will run your race-starting code, where you would perhaps run sound effects, start some AI drivers, move the camera in a certain way, and so on.

For clarity, understand that the three calls

  yield return StartCoroutine(PrepareRace());
  yield return StartCoroutine(Countdown());
  yield return StartCoroutine(StartRace());

must themselves be in a coroutine. That is to say, they must be in a function of the type IEnumerator. So in our example that's IEnumerator BeginRace. So, from "normal" code, you launch that coroutine with the StartCoroutine call.

 StartCoroutine(BeginRace());

To further understand chaining, here's a function which chains coroutines. You pass in an array of coroutines. The function runs as many coroutines as you pass, in order, one after the other.

// run various routines, one after the other
IEnumerator OneAfterTheOther( params IEnumerator[] routines ) 
{
    foreach ( var item in routines ) 
    {
        while ( item.MoveNext() ) yield return item.Current;
    }

    yield break;
}

Here's how you would call that...let's say you have three functions. Recall they must all be IEnumerator:

IEnumerator PrepareRace() 
{
    // codesay, crowd cheering and camera pan around the stadium
    yield break;
}

IEnumerator Countdown() 
{
    // codesay, animate your countdown on UI
    yield break;
}

IEnumerator StartRace() 
{
    // codesay, camera moves and light changes and launch the AIs
    yield break;
}

You'd call it like this

StartCoroutine( MultipleRoutines( PrepareRace(), Countdown(), StartRace() ) );

or perhaps like this

IEnumerator[] routines = new IEnumerator[] {
     PrepareRace(),
     Countdown(),
     StartRace() };
StartCoroutine( MultipleRoutines( routines ) );

To repeat, one of the most basic requirements in games is that certain things happen one after the other "in a sequence" over time. You achieve that in Unity very simply, with

  yield return StartCoroutine(PrepareRace());
  yield return StartCoroutine(Countdown());
  yield return StartCoroutine(StartRace());