Objective

The main objective of this blog post is to give you an idea about Coroutines in Unity3D.

 

Why do I have to use the update function every time?

What are Coroutines and how can I use them?

Why should I use Coroutines?

What are the best cases to use a Coroutine?

How can I sequence my game flow?

Some of you might be asking “What’s the deal with not using Update? I don’t see anything wrong with it!”

Well, ask the guys who used infinite Updates to get the game running so "SMOOTHLY" (That was sarcasm! in case you did not get that: P)

Imagine a case where you have 1000’s of Gameobjects and all of which have some execution in their Update() function.

Updates are called under any circumstances (given that they are defined)

Trust me, these Function calls may not be heavy on paper, but when you have so much of calculations executed every frame, outcome would not be so ideal.

Mind you, that does not mean that we have to stop using Update(), it is actually beautifully designed to get the work done.

It’s just that certain cases cannot be handled well with Update().

And this is where Coroutines comes into picture.

This post will be a theoretical journey, but please do bear with me on this one as it surely will be worth your while.

WHAT IS A COROUTINE..?

As Stated in Unity Docs,

"A coroutine is like a function that has the ability to pause execution and return control to Unity but then to continue where it left off on the following frame."

In simpler words:

"It is a special type of function used in Unity to stop the execution until sometime or certain condition is met, and continues from where it had left off."

HOW TO USE THIS SPECIAL FUNCTION..?

Firstly, remember one thing, don’t forget to use IEnumerator as a data type of function and second is, we can only start a Coroutine with function called "StartCoroutine(name of Coroutine)".

Before going further I recommend you have a look at WaitForSecond, Yield, so it would become easier for you to understand.

How was it? Did you catch any the balloons?

If yes then well and good and if not, well that's what I'm here for after all ;)

As Stated in the Unity Document,

"It is essentially a function declared with a return type of IEnumerator and with the yield return statement included somewhere in the body. The yield return line is the point at which execution will pause and be resumed the following frame".

Here, Yield is like return type statement where execution gets stopped and goes to the function where it was invoked. After execution, it comes back to a point from where it left the execution and starts executing next lines.

Let us consider an example of fading an image in specific time:

Step 1) Take a Canvas and a Panel inside it.

Step 2) Create an empty C# Script (I prefer coding in C#) and you can name it as you like.

Write the following code in your script:

PerformFadding

Step 3) Assign it to the panel and hit the play button in your Unity to see the magic.

Isn’t it fascinating?

I'll explain the magic; here PerformFadding() is a Coroutine where fading is performed. As I said earlier, you need to call the Coroutine with StartCoroutine() function.

As you can see from code that Coroutine is invoked on pressing the 'F' Key. When it is executed, it starts increasing alpha of the image bit by bit every frame until it's done.

It's almost like it started a parallel execution to fade the screen.

Here we have calculated the amount to increment (value of i) for each frame execution, i.e. how much should the Alfa be increased, depending upon the given time.

Thus Alfa will increase a fixed amount every frame and hence create a proper illusion of a fading image

Oh wait that’s not all! There is an option to delay the execution as per your wish. Isn't that great?

This can be achieved by using WaitForSecond function. Isn’t it convenient? Well trust me, it is!

FfadeEffect

Here, execution waits for some time as specified in the function and resumes afterwards. It is repeated until Coroutine finishes its execution.

Let’s again take the same example and change yield statement as shown in the code above. After changing in the line of yield, save it and push play button in Unity.

Did you see any change in fading behavior?

Yes, the fading was slow and performed in intervals

Here WaitForSeconds() waits for specified amount of time (in our case it is 0.5 f => 2.5/5 = 0.5f) and then continues its execution again.

For better understanding, play around with different values to see the effect of WaitForSeconds(). WaitForSeconds() is a very useful in sequencing animations and stuff.

WHY SHOULD I USE COROUTINE AND NOT UPDATE..?

You might be wondering Coroutine works just like Update, then why Coroutine?

Well, Update is generally used for things where same things are performed every frame

Whereas Coroutines are best when you want to schedule some events.

Imagine you have a visual effect to be performed every few minutes.

Now let’s say we used it in Update(). How will you handle execution when nothing is to be performed? (As Update() will be called even though nothing is to be done)

Alternatively we can use some boolean like "isPlaying"? But the main problem is it's sloppy, since Update() will needlessly keep checking this long after the desired effect is over

This would be something like calling out someone continuously knowing that no one is supposed to respond! Waste of Energy Isn’t it?

By using Coroutine your code gets shorter and it does help in optimization of code. (But it’s debatable)

Coroutines have only a tiny overhead and can be preferred over an Update method that is called all the time needlessly.

Don’t forget about what I had said earlier, Coroutine is not a substitute of Update!

THAT’S WONDERFUL, BUT WHERE AND WHEN CAN I USE COROUTINES..?

Typically there are three situations where it makes a lot of sense to use coroutines (that I can think off the top of my head).

  1. When you want to sequence things like animations and state machines
  2. When you want to split execution over multiple frames
  3. When you want to work on some asynchronous stuff(Like network requests)

So let us dig deep into this stuff:

1. When you want to sequence things like animations and state machines

Have a look on the following code:

IEnumerator PerformPlayerMotion()
{
        player.ChangeAnimatorState (PlayerAnimator.AnimatorState.Move);
        PlayerControl.RaiseOnChangeCameraMode (CameraScenematic.CameraMode.PlayerMovement);
        Yield return StartCoroutine(player.PerformMovement());
        player.ChangeAnimatorState (PlayerAnimator.AnimatorState.Idle);
        Player.StopNow();
        Yield return new WaitForSeconds(1.0f);               
}

Yes this is how sequences are maintained in games.

Here, first animation state is changed, then the camera state is changed , and it waits till the movement of player is over. As soon as the player movement is over the state is changed back to the idle and respective motion method is called.

For smooth ending another WaitForSeconds() is set.

Now if you check the third line, another coroutine is called player.PerformMovement(), Yes its possible! Now by using yield ahead of the StartCoroutine(), this will force the current coroutine to wait until execution of player.PerformMovement() is completed.

This is how you can handle a sequence in your games. It’s not perfect, but a possible solution.

2. When you want to split execution over multiple frames

Have a look on the following code:

IEnumerator PerformGridCalculations()
{
    for (int i = 0; i < 1000; i++)
    {
    	for (int j = 0; j < 1000; j++)
    	{ 
    		grid[i, j].DoSomeExpensiveCalculations();
    	}
    	yield return 0;
    }
}

Imagine a grid with items 1000 x 1000 and some calculation is to be done for each grid item!

That would take heck of a CPU to get that done smoothly (if executed in every single frame).

But luckily (because of Coroutines) there is a possibility that allows you to divide these heavy calculations into multiple frames and resulting in lesser CPU overload.

As seen in the code above, I have divided its execution in parts. Here only the j loop will be executed and cut off until it reaches the next frame.

In simpler words, only one loop of execution will be performed for the i loop in a single frame.

This is how Coroutines can also help optimizing games.

3. When you want to work on some asynchronous stuff(Like network requests)

Have a look on the following code:

IEnumerator LoginToFacebook()
{

    FB.Login();

    while (!FB.isLoggedIn())
    {
        yield return null;
    }

    SomeProccessOnLogin();
}

Now as shown above if you want to perform some initialization (or something like) that after an asynchronous process is completed, than there is no perfect solution other than coroutines!

Here I want to perform some stuff, after login to FB process is completed. So I’ll check if Fb.isLoggedIn() every frame. As soon as the condition turns true, required action will be executed.

Simple as that.

WOW COROUTINE ARE SURELY VERY USEFUL..!
BUT I WISH MORE OF IT..!

Does it get any simpler than this?

Oh wait, it does!

Recently Unity guys have added some new features to Coroutine which are WaitUntil, WaitWhile. These features can only be used with Yield statement.

They have added these features in recent release that is Unity version 5.3:

  1. WaitUntil suspends the execution until the given condition is true and
  2. WaitWhile suspends the execution until the given condition remains false.

To know more about WaitUntil and WaitWhile please checkout the following link:

COROUTINES SOUND LIKE ANGELS IN THE SKY..!
IS THERE ANYTHING WRONG WITH THEM..!

Coroutines come with a tag "HANDLE WITH CARE". Coroutines create a flow of logic which is incredibly hard to follow (as there is no explicit structure in how they execute or in what order).

And you end up creating an implicit dependency between them which varies depending on their execution order. Thus, if not used with proper understanding / care they can destroy your game structure (They won’t feel like angels now, would they?!!)

In addition, coroutines generate a bit of garbage when they are used so that’s another reason to be kept in mind.

Here we have a thumb rule that states,

"If you can't follow your coroutine logic, you've probably used one where you shouldn't have."

GREAT! READY TO USE COROUTINES IN MY GAME...!

I hope that’s what your feelings are right now. Just remember Coroutines are your friends as long you maintain proper relations with them. (Don’t cross that line) ;)

TRUST ME ON THIS ONE ,You don’t want to turn Coroutines into your enemies.

I hope this post turns out to be helpful, and still if you have any further doubts feel free to drop a comment below

Learning Unity sounds fun, right? Why not check out our other Unity Tutorials?

Got an Idea of Game Development? What are you still waiting for? Contact us now and see the Idea live soon. Our company has been named as one of the best Unity 3D Game Development Company in India.

Talented Game Developer as well as a player with a mania for video games and the game industry. Always Ready to take up challenging Projects. Proud to be making with the TheAppGuruz Team

face mask Belial The Demon Headgear Pocket Staff Magic