Hit Enter or
TAGS:  unity3d (9)  art (6)  experience (4)  hci (4)  virtual-reality (4)  vr (4)  ar (3)  computer-human-interaction (3)  digital-art (3)  generative (3)  installation (3)  interactive (3)  augmented-reality (2)  business-activation (2)  graphics (2)  math (2)  p5js (2)  research (2)  shaders (2)  tangible-interfaces (2)  algorithm (1)  app (1)  architecture (1)  arduino (1)  c# (1)  design (1)  iot (1)  maths (1)  mesh (1)  nft (1)  serial (1)  snapchat (1)  tools (1)  tutorial (1)  visualization (1)  work (1) 

Delayed code execution with Unity's coroutines

Sometimes a chunk of code must be executed one or more frames ahead, sometimes because it’s just convenient to do so, other times because your code simply wouldn’t work otherwise.

Mind that if you are in this situation, you should first ask yourself why. In fact, having to delay your code of one or more frames can be a symptom of engineering mistakes. But it may not depend on you. I had these situations in the past and the cause were most of the times external libraries or code from someone who left the company.

Unity exposes a very handy type called UnityAction to deal with delegates in a quick way. You almost don’t need any knowledge about delegates to use this approach, nonetheless I suggest you have a look at C# delegates.

A UnityAction may be roughly defined as a placeholder for a method. Below we define delayedAction Which accepts an UnityAction parameter. This allows us to pass our delegate which will be executed later in the body.

1
2
3
4
5
6
IEnumerator delayedAction(UnityAction action)
{
    yield return null; // optional
    yield return new WaitForEndOfFrame(); // Wait for the next frame
    action.Invoke(); // execute a delegate
}

Now the way to use it might seem a bit strange if you never wrote an anonymous method. In C# anonymous methods are considered delegates and are compatible with UnityAction so we will use an anonymous method to pass any code to our delayedAction.

1
2
3
4
5
StartCoroutine( delayedAction(() => {

    // DELAYED CODE HERE

}) );

This would execute all code in the next frame.

Of course you can bend the delayedAction method to your needs. For example you might want to use WaitForSeconds, or you might want to wait for n frames before Unity executes the delayed code. In that case:

1
2
3
4
5
6
7
8
9
IEnumerator delayedAction(UnityAction action, int nFrames)
{
    yield return null;
    for(int i=0; i<nFrames; i++)
    {
        yield return new WaitForEndOfFrame();
    }
    action.Invoke();
}

which would now be called as follows:

1
2
3
4
5
StartCoroutine( delayedAction(() => {

    // WRITE YOUR CODE HERE

}, 2) ); // for 2 frames delay