Adventures in GameDev with GameDevHQ! Day 16: Coroutines in Unity
Coroutines
One of the challenges in creating a space shooter is spawning enemies. Specifically having an enemy spawn every few seconds, so how could we do that? Unity offers us a tool called a Coroutine, according to the scripting API, a coroutine is “ a function that can suspend its execution (yield) until the given Yield Instruction finishes.”
To put it plainly, When you call a Coroutine, it will wait a specified amount of time with its yield command before executing its instructions and returning control to the calling function.
IEnumerator
One caveat, you don’t call a coroutine like any other function. It’s type is IEnumerator, and you always call it with StartCoroutine().
So for our example with the SpaceShooter, we need to spawn an enemy every 5 seconds. How do we go about this? We can create an object specific to that task. We can create an empty and call it Spawn_Manager then we can create a script called SpawnManager and attach it.
Because it will need a reference to the enemy prefab, we create a variable of the type GameObject and then drag the enemy into it.
Now we’ll have to make room for an enemy prefab inside of the SpawnEnemy script. Easy enough,
Now we just drag our enemy prefab into it.
Get ready to start spawning!
We know we want to spawn every 5 seconds. Personally, I like to put this in a variable, say _timeToSpawn. I will also put the top border position, 9, into a variable called yPos.
Next in the Start() function, we’ll get things going by prematurely calling the coroutine.
Now we use the IEnumerator to create the coroutine:
Fortunately, the top, left, and right borders are equal to 9 in the position when I checked the edges with the enemy, so we’ll just use that number for x and y limits when we spawn our enemy.
while it’s dangerous to use a while loop in this manner where it creates an infinite loop, we’re safe because the yield gives the computer time to breathe so we don’t have to worry about crashing.
so after waiting 5 seconds with the yield return new WaitForSeconds(5.0f) command, I create a random number between -9 and 9 which is the left and right borders of the screen. The number generated determines where on the screen the enemy ship will appear.
Next, we use a Vector3 using that random number for the x, the yPos variable for the y (remember it’s 9), and 0 on z because we’re currently not using the z axis.
And here is where we actually spawn the enemy using the Instantiate command! We take the enemy prefab, we give it the spawn position, and we use Quaternion.identity to basically tell unity we want this spawned with the default rotation info in the object. So let’s see this in action!
Hurray! It’s working perfectly!