Creating a Wave System for the Enemies

This tutorial covers creating a wave system for the enemies. This will limit a certain number of enemies at a time and wait for the player to destroy all the enemies in the wave before starting a new wave. To start you will need to create a UI element for the Wave. This will tell the player what wave they are on. This is not covered in this tutorial. If you need a review of how to create a UI element refer to this tutorial.

First, got to the SpawnManager script and add variables for the wave, the number of enemies, the number of enemies to spawn, the move type of the enemies as an int, and one to for the UIManager. Make sure you assign the UIManager variable in the Start function.

private int _waveNumber;
private int _numEnemies;
private int _numEnemiesToSpawn;
private int _moveType;
private UIManager _uiManager;

Next, create a function that reduces the number of enemies. This will be called by the enemy when they die.

public void OnEnemyDeath()
{
_numEnemies--;
}

Then go to the Enemy script and add a reference to the SpawnManager. Make sure you initialize it. Then where you handle the death of the enemy use the OnEnemyDeath function you just created.

_spawnManager.OnEnemyDeath();

Next, add a function to handle the initialization of an enemy. This should take two inputs, one for the move type and one for if shields are active.

public void InitializeEnemy(int moveType, bool hasShield)
{
_moveType = moveType;
SetMoveDirection();
if (hasShield == true)
{
ActivateShield();
}
}

Remove any other spots that you set the move type, like in the Start function. Make sure your SetMoveDirection function is setup for all the moves you want to have.

Return to the SpawnManager script. Now you will update the SpawnEnemyRoutine. To do this add an if-else statement. Check if the number of enemies is 0. If it is start a new wave. Increment the wave number. Set the number of enemies to the wave number times two. This way the number of enemies will continue to increase. The number of enemies to spawn will start the same as the number of enemies. These will be used for separate purposes. The number of enemies is reduced as enemies are killed and used to know when to start a new wave. The number of enemies to spawn will help keep track of how many more enemies need to spawn in the wave. All enemies in a wave have the same move type. Reduce the wave number by 1 and then take the modulo of using the number of move types. Then update the wave number in the UI.

if (_numEnemies == 0)
{
_waveNumber++;
_numEnemies = _waveNumber * 2;
_numEnemiesToSpawn = _numEnemies;
_moveType = (_waveNumber - 1) % 4;
_shieldTrigger = ((_waveNumber - 1) % 12) / 4;
_uiManager.UpdateWave(_waveNumber);
}

Then in the else statement is where you will instantiate and initialize the enemy. First check that there are still enemies to spawn. Then set if the enemy will have a shield. In the example below it is set for four waves with no shields, 4 waves with every other enemy shielded, and then for waves with all enemies shielded. It then instantiates the enemy as before but the calls InitializeEnemy passing it the move type and if it should have a shield. Remember to add the line to decrement the number of enemies to spawn at the end.

else
{
if (_numEnemiesToSpawn > 0)
{
bool hasShield = false;
switch (_shieldTrigger)
{
case 0:
hasShield = false;
break;
case 1:
if (_numEnemiesToSpawn % 2 == 1)
{
hasShield = true;
}
break;
case 2:
hasShield = true;
break;
default:
hasShield = false;
break;
}
Vector3 posToSpawn = new Vector3(Random.Range(-8.0f, 8.0f),
7.0f, 0);
GameObject newEnemy = Instantiate(_enemyPrefab,
posToSpawn, Quaternion.identity);
Enemy enemy = newEnemy.GetComponent<Enemy>();
enemy.InitializeEnemy(_moveType, hasShield);
newEnemy.transform.parent = _enemyContainer.transform;
_numEnemiesToSpawn--;
}
}

That is all you need to implement a wave system for the enemies.

-Chris

--

--

--

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

How to leak memory with Disposables in RxJava2

Top five reasons to learn Android Development in 2022

Want a simple, secure, and efficient file storage ? Try Huawei Cloud Storage Kit

How to Cook the 60 FPS RecyclerView?

Android guide: Fragment states

Huawei Ads Kit Using Reward Ads

Save an image with Coroutines and MediaStore in Koltin

Git-based Android App Versioning with AGP 4.0

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Christian Carter

Christian Carter

More from Medium

Quick tip — Upgrading your Unity project to High Definition Render Pipeline (HDRP)

Creating An Advanced 2D Player Controller Without Any Unity Components! (Part 2)

2.5D Platformer — Improving the Ledge Grab #10

Script Communication in Unity Using GetComponent<>