Menu
CoddyTech

Waves of Enemies

Part of the Game Architecture in Unity section of Coddy's Unity journey. Lesson 44 of 50.

challenge icon

Challenge

Medium

The enemies now come in waves, and the waves are data. Keep everything from the earlier lessons. The arena has no enemies of its own any more: the Grunt and Dasher prefabs carry your scripts, four spawn points stand in the corners, and the Spawner object in the middle has the WaveSpawner script.

  • In WaveSet.cs, add a [System.Serializable] class Wave with public Enemy enemy (the prefab), public int count and public float spacing. WaveSet is a ScriptableObject with [CreateAssetMenu], a public List<Wave> waves and a public float restBetweenWaves. The scene's Arena asset holds three waves (3 grunts 0.5 s apart, 2 dashers 1 s apart, 5 grunts 0.4 s apart) and a rest of 2 seconds.
  • Enemy gets public static event Action<Enemy> Died, raised with the enemy right before it is destroyed.
  • WaveSpawner has waveSet and spawnPoints from the Inspector, and public int Wave { get; private set; }, the number of the wave in play. From Start, a coroutine runs the asset's waves in order. For each: add 1 to Wave and log it, as Wave 1; spawn the wave's count enemies spacing seconds apart, enemy i (from 0) at spawnPoints[i % spawnPoints.Length]; wait until no enemy is left alive; then rest restBetweenWaves seconds. After the last wave the set starts again from its first, and Wave keeps counting: 4, 5 and so on.
  • Count the enemies alive with the Died event: subscribe in OnEnable and unsubscribe in OnDisable. The spawner only reads the asset: in the Editor, a change made to an asset while the game runs stays in the asset after Play.

Press Play and survive a few waves, then Check.

Try it yourself

using UnityEngine;

public class WaveSpawner : MonoBehaviour
{
    // A later lesson fills this in: sends the waves into the arena.
}

All lessons in Game Architecture in Unity