An introduction to Coroutines with Unity!
Objective: understanding the basic purpose of coroutines, and explore how to implement them in Unity.
When I first began coding with Unity, I found myself putting all my code into the Update() function. Why? Well, it simply made sense to me at the time since everything within Update() was called every frame, and the low level of complexity of my apps gave the appearance that this practice was just fine and would not tax my old laptop’s processor. It didn’t take me long to figure out that all code can’t just simply be executed continuously, either because they were becoming just a drain on my limited resources, or more because they simply did not need to run all the time.
This is where the use of Coroutines comes in.
“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.” https://docs.unity3d.com/Manual/Coroutines.html
Coroutines are ways to write code that says “wait at this line for a little”. It allows you to execute code over a number of frames, in intervals. Any time you want to do a sequence of events, or order of events, a coroutine is a great choice to use.
Let’s say you had this little cube just going back and forth in your game screen. You call the MoveThatCube() function inside void Update(), and while the cube is moving along, your program waits for the user to press the Space key in order to initiate the coroutine FirstCoroutine().
You declare the coroutine with a return type of IEnumerator, along with a yield return statement somewhere in the body of the code. Using IEnumerator is how Unity extends the execution of the function over multiple frames. Yield statements that let us know that our method is an iterator and will run for multiple frames.
isCoroutineRunning bool gets set to TRUE, which stops the Space key from being registered, therefore preventing the coroutine to be called while it is running. This is set back to FALSE before exiting the coroutine.
yield return null; — waits for a full frame, then continues on.
yield return new WaitForSeconds(3.0f); — waits for 3 seconds, then continues on.
In order to run a IEnumerator coroutine, you need to use the keywords StartCoroutine(NameOfCoroutine()).
StartCoroutine(NameOfCoroutine()) — using Type (faster).
StartCoroutine(“NameOfCoroutine”) — using String (slower), allows us to stop the coroutine using StopCoroutine(“NameOfCoroutine”).
In order to appreciate the flexibility of coroutines, let’s look at the script in action:
You can see how, upon striking the Space key, the coroutine is called and events are executed at intervals. There is even a second coroutine called by the first coroutine. All this occurring while the cube is being translated across the screen by the Update() function.
Coroutines are a great tool to execute chunks of code in a synchronized way. Keep in mind this is only an introduction and we have only scratched the surface in this article. I hope I’ve managed to clarify a few of the nuances involved.