Coroutines with Unity!
A Coroutine is a method that can pause execution (yield) but then continue where it left off when the yield has finished. A standard method executes the entire code in that frame.
To create a Coroutine, you start with IEnumerator instead of void like a regular method. Next, you need a yield instruction for the Coroutine, or else it will give you an error. To create a yield instruction, start with yield followed by return and then the amount of time that it needs to wait before continuing where it left off through a new WaitForSeconds (there are many types of WaitFor). The yield tells the Coroutine to pause and return control to Unity to complete the frame and then return to the Coroutine when the WaitFor is complete.
It is common to use a while loop inside a Coroutine. A while loop will continue to run over and over till the set condition is met. Leaving a while loop with a condition that will always be true is called an infinite loop and is very dangerous. An infinite loop is scary because it will continue to run till either the program stops or your computer locks up from lack of memory. That is why you want to put a yield in an infinite loop, so it gives your computer some time to breathe. Typically you only use an infinite loop for something that you want to happen for the program’s length.
To begin a Coroutine, you can call it with StartCoroutine and then the Coroutine name you want to start. You can either call it like a method or search for it by string.
Spawning Enemies
Now that we have gone over the basics of a Coroutine, let’s make an example of one for the spawning of Enemies made in previous articles.
First, create an Empty gameobject and name it “Spawn Manager”. Then create a new script, call it “SpawnManager”, and attach it to the Spawn Manager gameobject.
In the SpawnManager script, create a private GameObject variable named “_enemyPrefab” with a null value to hold a reference to the Enemy Prefab that the script will spawn. Then, create a private Transform variable named “_spawnPoint” with a null value to hold a reference to the enemies’ spawn point.
Next, create a new Coroutine named “SpawnRoutine”. Inside the Coroutine, create a while loop with the condition of true. Inside it, create a float named “randomX”, equal to a random number between the range of -8 and 8. Create a Vector3 named “spawnLocation” equal to a new Vector3 with the x of randomX, y of the _spawnPoint y position, and z of 0. Then add an Instantiate that will spawn an _enemyPrefab at the spawnLocation with a rotation of Quaternion.identity. Finally, have the Coroutine yield and wait for 5 seconds before repeating.
The Coroutine needs to be started, so in the Start method, begin the Coroutine with StartCoroutine and call the SpawnRoutine.
Finally, set all the position values on the Spawn Manager gameobject to 0 and drag the Enemy Prefab into the Enemy Prefab field. Then create an Empty gameobject as the Spawn Manager’s child and name it “Spawn Point” and set the y-axis position to 8. Drag the Spawn Point gameobject into the Spawn Point field on the Spawn Manager.
You can now enter Play Mode and see the enemies continuously spawning.
Now the Enemy gameobjects are cluttering the Hierarchy. We will fix that and stop the spawning of enemies when the Player gets destroyed in the following article.