2D Space Shooter 4: Enemies

Jeff Minnear
4 min readMar 25, 2021

--

Continued from part 3.

So now we can shoot. That’s great, and there’s certainly fun to be had firing wildly into the air, but I think most people would agree it’s more fun to shoot at something. Let’s make some enemies!

At this point you’re already familiar with prefabs and instantiation, and we’re about to use both again. Add a new 3D Object > Sphere to the hierarchy and name it “Enemy”, reset the transform, and drag it into the Prefabs folder.

Create a new C# script named “Enemy” and add it to our Enemy prefab. We want our enemies to move from the top of the screen to the bottom and then reappear at the top to start the process over again. That sounds an awful lot like the opposite of what our lasers do. And not surprisingly, the code is pretty similar.

Everything here should look pretty familiar. We use the Translate method to move the enemy straight down (Vector3.down being the exact opposite of Vector3.up), but instead of destroying it when it gets off screen, we just warp it back to the top by directly assigning transform.position. Those two additional floats (maxYPosition and minYPosition) are based on the vertical limits of the screen in my aspect ratio. If you’re using something other than 16:9, you may need to tweak these values. Drop an enemy into the hierarchy and here’s what you get:

That’s pretty much what we’re going for, but wouldn’t it be more fun if you didn’t know exactly where the enemy was going to reappear? We can achieve this very easily by adding a random X value (constrained by the screen width) when we set transform.position.

Random.Range returns a random (well, technically not but pretty close!) value between two reference values (our min and max X values). Let’s see this in action:

That’s way more interesting. But we don’t want to have to manually drag enemies into the scene, so let’s create an object that can spawn them. Create an Empty GameObject called “SpawnManager”.

Create a new C# script for our SpawnManager and attach it to the new game object. Give it a public GameObject Enemy, save the script, and in the editor drag the Enemy prefab into the new slot just like we did with the Laser prefab on the Player. Now we need some logic to instantiate enemies.

Time.time is simply the number of seconds since the game started. By subtracting the lastSpawnTime, we can figure out whether it’s been long enough since the last enemy was created to create another. The rest uses the same pattern we used in the Enemy script to randomize the spawn point, and creates a new enemy using our old friend Instantiate. However…

Things get out of hand pretty quickly. So let’s limit the number of enemies on screen to 5 and increase the time between spawns a little. Before we write the code, let’s add a tag to our Enemy prefab. Tags help GameObjects identify each other and will be useful when we start blowing things up in the next post. Creating and assigning tags happens in the editor and can be done like this:

Now that we have a tag on our prefab, we can reference it in the SpawnManager script to figure out how many enemies are currently in the game. Create the following function:

GameObject.FindGameObjectsWithTag returns an array of every active GameObject with the given tag. We don’t actually need the entire array, so we’ll just return it’s length property.

Now we just add a maxEnemies variable and check if it’s been reached before we spawn. Here’s the final code:

And that’s it. See you next time, when we’ll start blasting enemies and scoring those sweet, sweet points!

Continued in part 5.

--

--

Jeff Minnear
Jeff Minnear

Written by Jeff Minnear

Jeff is a software developer and musician. He’s quite fond of red curry.

No responses yet