Wave Spawner
Wave Spawner
This scriptable object provides configuration for the various waves used when the Runtime Spawner has Wave Spawning enabled.
To Create a new Wave Spawner config you can Right Click in the Project window and go to ‘Create Other ⇒ Runtime Spawner ⇒ Wave Spawner’
Or use the Assets menu (Create ⇒ Runtime Spawner ⇒ Wave Spawner)
This will create an empty Wave Spawner, as shown below:
Click the ‘+’ button to create new Waves.
Below is a screenshot of a populated Wave Spawner

Properties (WaveSpawner)
Description Free‑form text for identifying the spawner (queryable in‑game).
Spawn Delay (
float 0..10) Initial delay before the first wave starts.Wave Interval (
float 0..10) Delay inserted after a wave completes (including any looping) and before the next wave starts.Waves (
List<WaveEntry>) The ordered list of waves. Use + to add waves.
Validation: On edit, each wave auto-fills its name if blank and clamps counts (see below).
Wave Configuration (WaveEntry)
Wave Info
Name (
string) Display name. If blank, auto‑fills toWave {index+1}.Description (
string) Optional, queryable in‑game.
Wave Timing
Spawn Delay (
float 0..10) Delay before this wave begins.Spawn Instance Interval (
float 0..10) Delay between spawning each agent within this wave.Spawn Count Min / Max (
int 1..100) A random inclusive count in[Min, Max]is chosen when the wave runs.spawnCountMinis clamped to ≥ 1.spawnCountMaxis clamped to ≥spawnCountMin.
Loop Policy (per wave)
Defined by LoopPolicy:
Type (
LoopType)None – Run the wave once (legacy behavior).
Duration – Repeat the wave until
durationSecondshave elapsed.MaxLoops – Repeat the wave up to
maxLoopstimes.0 means unlimited (no cap).
UntilSignal – Repeat until a signal with id
untilSignalis received.
durationSeconds (
float ≥ 0) Used whenType = Duration.maxLoops (
int ≥ 0) Used whenType = MaxLoops(0 = unlimited).untilSignal (
string) Used whenType = UntilSignal; integrates with your signal bus.restSeconds (
float ≥ 0) Optional pause between loop iterations (applies to all loop types exceptNonesince it doesn’t loop).shuffleOnLoop (
bool) When true, each loop iteration shuffles the wave’s valid spawn entries and then cycles through that shuffled order without immediate repeats.
Loop execution specifics (from WaveTableRunner + WaveSpawnLoop)
WaveTableRunner + WaveSpawnLoop)Table-level Spawn Delay runs once before the first wave.
For each wave:
If
Type = None: wave runs once.Otherwise: the runner calls the wave executor repeatedly, enforcing:
Duration: stop when elapsed time ≥durationSeconds.MaxLoops: stop whenloops ≥ maxLoops(unless 0 = unlimited).UntilSignal: stop when the signal bus reports theuntilSignalwas fired.
restSecondsis inserted between iterations of the same wave.
After a wave (and its loops) finishes, table-level Wave Interval is applied before the next wave.
Wave Spawners
Spawners (
List<SpawnEntry>) The spawn configurations used by this wave. See Spawn Entry docs for fields.
Runtime behavior notes
Validation of entries: entries that are
nullor missing aprefabare skipped with a warning and won’t be selected.Spawn count selection: the chosen count respects inclusive Max (internally handled with the exclusive
Random.Rangeoverload).Entry selection within a run:
With shuffleOnLoop = true: the executor Fisher–Yates shuffles the local list and then walks it in order (
spawned % count), preventing immediate repeats until the list cycles.With shuffleOnLoop = false: each spawn picks a random valid entry.
Spawn points: if the initiating WaveTrigger provides
WaveSpawnPoints, those are preferred; otherwise, the spawner uses the trigger (or owner) transform with a default range. (SeeWaveTriggerdocs for configuring explicit wave spawn points.)
Editor Validation (OnValidate)
For each wave:
Auto‑names if blank (
Wave {index+1}).Clamps counts to valid ranges (
Min ≥ 1,Max ≥ Min).
Signal Bus Integration
The Loop Policy UntilSignal mode relies on a lightweight static SignalBus system.
This allows a wave to repeat until a specific string signal is fired by your game logic.
How it works
Signals are string IDs.
Once a signal is fired, it stays latched until it is consumed or explicitly cleared.
The
WaveTableRunnerchecksSignalBus.WasFired(untilSignal)each loop.If the signal has been fired, the wave loop ends.
By default,
WasFiredconsumes the signal (removes it from the fired set).
API Summary
SignalBus.Fire(string id)Latches a signal by ID. No-op ifidis null/empty.SignalBus.WasFired(string id, bool consume = true)Returnstrueif the signal was previously fired. Ifconsume = true(default), the signal is cleared after the check.SignalBus.Clear(string id)Clears the fired state of a specific signal.SignalBus.ClearAll()Clears all fired signals.
Usage Example
// Somewhere in your gameplay logic:
if (bossDefeated)
SignalBus.Fire("BossDefeated");
// In a wave config:
loopPolicy.type = LoopType.UntilSignal;
loopPolicy.untilSignal = "BossDefeated";In this example, the wave will keep repeating until your game logic fires the "BossDefeated" signal.
Last updated