Menu
CoddyTech

Oczyść arenę

Część sekcji Architektura gier w Unity ścieżki Unity w Coddy. Lekcja 55 z 64.

Zdarzenie oznaczone jako static należy do klasy, a nie do pojedynczego obiektu. Istnieje jedno Enemy.Died dla wszystkich wrogów, jacy kiedykolwiek powstaną, więc spawner może zasubskrybować je za pomocą Enemy.Died += OnEnemyDied;, zanim powstanie jakikolwiek wróg, a każdy wróg wywołuje je, przekazując siebie jako argument. Ten sam pomysł w czystym 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;   // Na razie nie potrzeba obiektu Coin
    }

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

Do zdarzenia instancji odwołujesz się przez obiekt, na przykład hero.Died; do zdarzenia statycznego — przez nazwę klasy, na przykład Coin.Picked. Zdarzenie statyczne istnieje dłużej niż każdy obiekt, dlatego odepnij subskrypcję w OnDisable, bo zniszczony spawner pozostanie na liście.

challenge icon

Wyzwanie

Średni

Spraw, by każda fala czekała, aż arena będzie pusta.

  1. W Enemy dodaj public static event Action<Enemy> Died; i wywołaj Died?.Invoke(this); tuż przed Destroy(gameObject);.
  2. W WaveSpawner zliczaj alive: dodawaj 1 przy każdym pojawieniu się przeciwnika, a w metodzie, którą OnEnable dodaje do Enemy.Died, a OnDisable z niego usuwa, odejmuj 1.
  3. Po pojawieniu się fali poczekaj, aż alive > 0 przestanie być prawdą.

Naciśnij „Graj” i pokonaj falę 1: fala 2 pojawi się 2 sekundy później. Następnie naciśnij „Sprawdź”.

Spróbuj swoich sił

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);
            }
        }
    }
}

Wszystkie lekcje w sekcji Architektura gier w Unity

Poćwicz samodzielnie: Edytor online Unity