Jump to content
  • entries
  • comments
  • views

Day 23 of 100 Days of VR: Creating a Spawning System for Enemies in Unity

Josh Chang


Here we are back to another day of Unity development! Today on day 23 we’re going to learn how to spawn enemy waves.

Currently, the game isn’t challenging, we only have one enemy!

Today, we’re going to fix this by spawning waves of enemies to defeat, making the game a lot tougher to survive!

It’s going to be a big change requiring multiple days, so let’s get right to it!

Creating an Enemy Wave Spawning Point

If we were to recall from the Unity Survival Shooter tutorial, to spawn enemies, we need to create a SpawnManager class that creates new instances of the enemy.

In our Spawn Manager, the primary thing we need to give it, among many other things that we’ll want to add, are the:

  • location of where we would spawn the enemies
  • enemies that we want to spawn

However, as a challenge, as opposed to the Survival shooter, where the game would continue for it, we’re going to have a limited amount of enemy spawn so we can win.

There was a lot of work involved in the wave system and I borrowed a lot of ideas from Unity’s Enemy Spawner example.

Creating the initial game objects

The first thing we want to do is create a new Empty Game Object that we’ll call EnemyManager. We’re going to make this a child of our GameManager.

Next, we’ll create a new script for our new game object that we’ll call EnemyManager.

We’re going to do a couple of things with our manager:

  • Keep track of what wave we’re in
  • Keep track of how many enemies we defeated in a wave
  • Keep track of how many enemies per wave

By keeping track of the number of enemies and waves, we can tell when to move to the next wave and if we win.

Here’s our initial code for EnemyManager.cs:

using System.Collections;
using UnityEngine;
public class Wave
    public int EnemiesPerWave;
    public GameObject Enemy;
public class SpawnManager : MonoBehaviour
    public Wave[] Waves; // class to hold information per wave
    public Transform[] SpawnPoints;
    public float TimeBetweenEnemies = 2f;
    private int _totalEnemiesInCurrentWave;
    private int _enemiesInWaveLeft;
    private int _spawnedEnemies;
    private int _currentWave;
    private int _totalWaves;
	void Start ()
	    _currentWave = -1; // avoid off by 1
	    _totalWaves = Waves.Length - 1; // adjust, because we're using 0 index
    void StartNextWave()
        // win
        if (_currentWave > _totalWaves)
        _totalEnemiesInCurrentWave = Waves[_currentWave].EnemiesPerWave;
        _enemiesInWaveLeft = 0;
        _spawnedEnemies = 0;
    // Coroutine to spawn all of our enemies
    IEnumerator SpawnEnemies()
        GameObject enemy = Waves[_currentWave].Enemy;
        while (_spawnedEnemies < _totalEnemiesInCurrentWave)
            int spawnPointIndex = Random.Range(0, SpawnPoints.Length);
            // Create an instance of the enemy prefab at the randomly selected spawn point's position and rotation.
            Instantiate(enemy, SpawnPoints[spawnPointIndex].position, SpawnPoints[spawnPointIndex].rotation);
            yield return new WaitForSeconds(TimeBetweenEnemies);
        yield return null;
    // called by an enemy when they're defeated
    public void EnemyDefeated()
        // We start the next wave once we have spawned and defeated them all
        if (_enemiesInWaveLeft == 0 && _spawnedEnemies == _totalEnemiesInCurrentWave)

Now this is a lot to take in, which is why I added comments, however, here’s the run through of the code.

About the Wave Class

Before we talk about our variables, I want to introduce the Wave class.

Wave is a container for us to hold the data for each wave that we’re going to face.

If you remember from the Space Shooter tutorial, we did something similar. We created a new class to hold information and we made it Serializable so that Unity knows how to show it in the editor.

Originally, I was going to just pass each of its content to our SpawnManager, but that’s prone to us causing mix-ups of how many enemies to spawn per wave and which enemies.

About the variables

For our public variable we have:

  • Waves — An array of the Wave class that we created for an easy way for us to access data for each wave
  • SpawnPoints — An array of locations that we’re going to instantiate our enemies
  • TimeBetweenEnemies — The delay we wait before we spawn our next enemy

For our private variables to keep track of the enemies, we have:

  • _totalEnemiesInCurrentWave — Self explanatory
  • _enemiesInWaveLeft — The number of enemies that are still alive in the wave
  • _spawnedEnemies — Self explanatory

We also keep track of what wave we’re in:

  • _currentWave — Self explanatory
  • _totalWaves — Self explanatory

The Code Flow

Now that we know the variable we’re using, we can walk through the rest of the code.

  1. In Start() we initialize all our variables to 0. Note that we set _currentWave to be -1 and our _totalWaves is the length of our array — 1. For those who aren’t familiar, all of this is, because we’re working in a 0-based indexing for arrays (meaning everything starts from 0 instead of 1).
  2. From Start() we also call StartNextWave() this code handles what happens when we clear our wave. We increment our _currentWave and assuming we haven’t finished the game, we’ll setup the enemies we need to encounter for the next wave and call SpawnEnemies()
  3. SpawnEnemies() is a coroutine that we use to create our enemies. The function will spawn the enemy for the wave based from one of the random spawn points we set. The code will wait 2 seconds before we spawn the next enemy so we don’t flood the players with all the enemies in a wave at once.
  4. Finally, we have public EnemyDefeated() which means this function is called from something else. In this case, our enemy will call this when they’re killed. We will then decrement our enemy counter and if we have defeated all the enemies in a wave, we’ll call StartNextWave()

That’s the basic summary of the code. That wasn’t so bad, now was it? RIGHT?!

Setting up our SpawnManager script

Now that we have our script up and running, the last thing we need to do is to setup our Wave and create our Spawn Points.

Setting up the Wave

For now, let’s just make 2 waves for our SpawnManager that will create our knight enemy.

There are 2 things we need to provide for our Wave class:

  • The knight game object
  • How many enemies to spawn for the wave

Let’s first set the knight game object.

We could just drag and drop our knight from our hierarchy into the spot and everything would be fine. However, the correct way to do this, is to first create a prefab of our knight.

We can think of a prefab is a template of a game object that we can drag and share to different scenes and games. In our case, we can also instantiate them like what we’re doing here.

The main benefit is that, if you were to change prefab, anytime we need to change something, we can just change the prefab and anything that instantiates it from code will also get the changes.

The first thing we’re going to do is:

  1. Create a folder in our Assets folder called Prefabs
  2. Create our prefab, by dragging our Knight game object into the PrefabsNote, in this example our Knight is already a prefab, but that’s okay, we’ve already changed some things about it, so let’s make another prefab from it.

On a side note: we can delete the Knight game object from our hierarchy. He’s served us well, but we won’t be needing his services anymore.

Now that we have everything we need, we can get started in Creating our waves.

Back in our SpawnManger script, expand Waves and set Size to be 2 so we can create new waves.

Here’s what it’ll look like:


Setting up the Spawn Point

Now that we have the wave system setup, we need to create our spawn points.

Exactly like the survival shooter, we need to add some game object that we’ll use as the location that we’re going to spawn the enemies.

Let’s get to it!

Create 3 Empty game objects: I call them SpawnPoint1 — SpawnPoint3. I made them the child of the SpawnManager, however, it doesn’t really matter where we put them.

Right now, we can’t see the position of our SpawnPoints in the game, however we can add a Label to them to see where the objects are.


We just want to set the Spawn points to be in 3 of the houses.

Here are my Position values, yours might be different:

SpawnPoint1: 98, 0, 118

SpawinPoint2: 72, 0, 89

SpawnPoint3: 106, 0, 80

Finally, go back to our SpawnManager and add our SpawnPoints in.

Expand Spawn Points and then for the Size change it to 3, and then drag our SpawnPoints into the empty game spots.


With all of this in place, if we play the game, we should now have multiple enemies coming at us.



We’re not quite done with our Spawning System, however we laid the ground works for spawning enemies.

We still need to implement the logic for generating new enemies and finally creating our victory condition. We’ll start implementing those tomorrow on Day 24!

With that being said, have a good night!

Source: Day 23

Visit the 100 Days of Unity VR Development main page.

Visit our Homepage


Recommended Comments

There are no comments to display.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Advertisement
  • Advertisement
  • Blog Entries

  • Similar Content

    • By GameTop
      Dirt Bike Extreme - another game made with Unity. Took about 2 months to complete.
      Take part in extreme motorcycle races across the dangerous and challenging tracks. Dirt Bike Extreme is easy to pick up but hard to master. Race, jump and crash your way and other mad rivals through the amazing tracks as you master the skills and physics of motocross in this high-speed racing adventure. Conquer challenging routes on 23 different runs, discover new bikes and become the best of the best! Over 257K downloads already!
      Windows Version:

      Mac Version:


    • By Sergio Ronchetti
      Continuing to work on “Eldest Souls” (first article here!), I’ve begun familiarising myself with the workflow between Fmod and Unity, and the integration system. I know much of this will be pretty obvious to most, but I thought I’d share my thoughts as a complete beginner learning the ropes of sound designing. 
      The library of sounds that Fmod provides has been very useful, at least as reference points. I’ve still kept to my ethos of producing the sounds myself as much as possible. Having said that, Fmod gives you 50 free sounds with your download, and I’ve used a wooden crate smash, a drawbridge and electricity sound you can hear in the foley video below.
      The thing i found most useful was witnessing changes i made in Fmod being realised instantly in Unity. If a volume needed changing, or the timing of one of my effects was off, i can literally switch to Fmod and then back to Unity and immediately see the result of my alterations. It also seems apparent that using middleware such as this (or i've heard Wwise is also equally intuitive) grants the developer, and myself included, a great deal more flexibility and opportunity to edit sounds without going all the way back to a DAW, and bouncing down again. Needless to say, my workflow is so much faster because of it.
      I've also loved the randomised feature of Fmod, whereby any sound can be made to sound slightly different each time it is heard. Taking a footstep recording i made for example, I was able to add further authenticity of uneven footsteps by randomising the pitch and volume of each playback. 

      I used this technique when creating footsteps for the first major boss in the game called "The Guardian". A big, over-encumbered husk of a monster. I also had fun rummaging through the garage for old tools and metal components for the “Guardian” (the first boss) footsteps. See below!
      I also created a sword attack for our player, trying to sound different from the generic “woosh” I see in so many video games. I used a very “sharp” and abrasive sound to differentiate him from any enemies.
      On another note, I recently upgraded my microphone to a Rode NTG2 shotgun, which has been phenomenal. I haven’t had to worry about noise interfering with the clarity of my objects, whereas before with the sm58 I had to be clever with my EQ and noise reduction plugins.
      Important to note again that this still a “cheap” mic in comparison to most other products on the market, and all in all my entire setup is still very simple and affordable which I’m quite proud of. I’ve seen many musicians spend heaps of money on gear they don’t necessarily need. I much prefer being resourceful with less equipment, than to have more than I can understand or remember how to use.
      It’s forced me to understand every aspect and capability of my tools, which I believe is a principal that can be applied to any discipline.
      I have more fun little sound effect videos on my Instagram for those interested, where I post regular updates. Thanks for reading! (if you’ve made it this far)
    • By Sergio Ronchetti
      Recently I joined the talented team at Fallen Flag Studio as the composer for their latest release "Eldest Souls" which consequently lead me into a field I have always dreamt of trying - sound design!
      Having no prior experience, I began watching a few online tutorials (if you want to learn from anyone make it Akash Thakkar from "Hyper Light Drifter"... what a guy!) and basically just testing stuff out i found around the house. Luckily my dad has a garage FULL of random crap to use.
      Before i continue, it's important to note that i DO NOT have fancy equipment, meaning anyone can try this. (my equipment is an sm58, focusrite scarlett interface and Logic Pro X plugins... that's it!)
      I started basic with some footsteps, which weren't all too difficult. Then I moved on to projectiles and a spear attack one of the bosses has. Below are a couple super short videos on my resulting attempts.
      Amazing how great a banjo sounds for that typical "woosh" sound! And if you're wondering, the paper was added to give some texture to the jab.
      I could be finding a lot of these sounds in libraries online (like the built-in ones that come with Fmod and Unity) but I've chosen not to, in order to produce authenticity and hopefully a more unique gameplay experience for players when the final product is put together.
      P.S. if you'd like to try the game and hear my hard work we'll be at EGX and several other conventions later this year, soon to be announced! Thanks for reading!
      To those interested, there's an Alpha trailer of the game in question below.
    • By OConquestGame
      Hello there!
      I’m the creator and producer of an upcoming visual novel / video game. 
      My team and I are looking for artists (character and background), writers (experienced in writing relatable characters and witty dialogue), and programmers (familiar with unity and creating mini games). 
      Our team is a group of close friends looking to break the mold of the traditional visual novel and create something new and positive. This game will be highly promoted and be a great portfolio piece. Rates are negotiable!
      If you are interested please contact/message us today! OConQuestGame@gmail.com
    • By Kamal Wafi
      Hi there,
      i recently start learning unity and im working in my first game ,
      I was wondering if unity had functions to support the motion control effect (tilting screen to move character) you see
      in doodle jump (which is 2d game) ? If it exists, what are they called? and how it works ?


Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!