Menu
CoddyTech

Räum die Arena

Teil des Abschnitts Spielarchitektur in Unity der Unity-Journey von Coddy. Lektion 55 von 64.

Ein als static gekennzeichnetes Ereignis gehört zur Klasse, nicht zu einem einzelnen Objekt. Es gibt genau ein Enemy.Died für alle Gegner, die es jemals geben wird. Daher kann sich der Spawner mit Enemy.Died += OnEnemyDied; anmelden, bevor irgendein Gegner existiert, und jeder Gegner löst es mit sich selbst als Argument aus. Dieselbe Idee in einfachem C#:

public class Coin
{
    public static event Action<Coin> Picked;

    public void Pick()
    {
        Picked?.Invoke(this);
    }
}

public class Purse
{
    private int coins;

    public Purse()
    {
        Coin.Picked += OnPicked;   // noch kein Coin erforderlich
    }

    void OnPicked(Coin coin)
    {
        coins++;
    }
}

Auf ein Instanzereignis greifst du über ein Objekt zu, wie bei hero.Died; auf ein statisches über den Klassennamen, wie bei Coin.Picked. Ein statisches Ereignis überlebt jedes Objekt. Melde dich daher in OnDisable ab, sonst bleibt ein zerstörter Spawner in seiner Liste.

challenge icon

Aufgabe

Mittel

Lass jede Welle warten, bis die Arena leer ist.

  1. Füge in Enemy public static event Action<Enemy> Died; hinzu und rufe Died?.Invoke(this); direkt vor Destroy(gameObject); auf.
  2. Zähle in WaveSpawner alive: Erhöhe den Wert bei jedem Spawn um 1 und verringere ihn in einer Methode um 1, die OnEnable zu Enemy.Died hinzufügt und die OnDisable entfernt.
  3. Warte nach dem Spawn einer Welle, solange alive > 0 gilt.

Drücke „Spielen“ und besiege Welle 1: Welle 2 kommt 2 Sekunden später. Drücke dann „Prüfen“.

Probier es selbst

using System.Collections;
using UnityEngine;

public class WaveSpawner : MonoBehaviour
{
    [SerializeField] private WaveSet waveSet;
    [SerializeField] private Transform[] spawnPoints;

    public int Wave { get; private set; }

    void Start()
    {
        StartCoroutine(RunWaves());
    }

    IEnumerator RunWaves()
    {
        while (true)
        {
            foreach (Wave wave in waveSet.waves)
            {
                Wave++;
                Debug.Log("Wave " + Wave);
                for (int i = 0; i < wave.count; i++)
                {
                    Transform point = spawnPoints[i % spawnPoints.Length];
                    Instantiate(wave.enemy, point.position, Quaternion.identity);
                    yield return new WaitForSeconds(wave.spacing);
                }
                yield return new WaitForSeconds(waveSet.restBetweenWaves);
            }
        }
    }
}

Alle Lektionen in Spielarchitektur in Unity

Übe selbstständig: Unity-Playground