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 to Wave {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.

    • spawnCountMin is clamped to ≥ 1.

    • spawnCountMax is clamped to ≥ spawnCountMin.

Loop Policy (per wave)

Defined by LoopPolicy:

  • Type (LoopType)

    • None – Run the wave once (legacy behavior).

    • Duration – Repeat the wave until durationSeconds have elapsed.

    • MaxLoops – Repeat the wave up to maxLoops times.

      • 0 means unlimited (no cap).

    • UntilSignal – Repeat until a signal with id untilSignal is received.

  • durationSeconds (float ≥ 0) Used when Type = Duration.

  • maxLoops (int ≥ 0) Used when Type = MaxLoops (0 = unlimited).

  • untilSignal (string) Used when Type = UntilSignal; integrates with your signal bus.

  • restSeconds (float ≥ 0) Optional pause between loop iterations (applies to all loop types except None since 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)

  • 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 when loops ≥ maxLoops (unless 0 = unlimited).

      • UntilSignal: stop when the signal bus reports the untilSignal was fired.

    • restSeconds is 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 null or missing a prefab are skipped with a warning and won’t be selected.

  • Spawn count selection: the chosen count respects inclusive Max (internally handled with the exclusive Random.Range overload).

  • 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. (See WaveTrigger docs 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 WaveTableRunner checks SignalBus.WasFired(untilSignal) each loop.

    • If the signal has been fired, the wave loop ends.

    • By default, WasFired consumes the signal (removes it from the fired set).

API Summary

  • SignalBus.Fire(string id) Latches a signal by ID. No-op if id is null/empty.

  • SignalBus.WasFired(string id, bool consume = true) Returns true if the signal was previously fired. If consume = 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