Menu
CoddyTech

Очистите арену

Часть раздела Архитектура игр в Unity путешествия по Unity на Coddy. Урок 55 из 64.

Событие с пометкой static принадлежит классу, а не отдельному объекту. Для всех врагов, которые когда-либо появятся, существует одно событие Enemy.Died, поэтому спавнер может подписаться на него с помощью Enemy.Died += OnEnemyDied; ещё до появления любого врага, а каждый враг вызывает это событие, передавая себя в качестве аргумента. Та же идея на обычном 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;   // Пока объект Coin не нужен
    }

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

К событию экземпляра обращаются через объект, например hero.Died; к статическому — через имя класса, например Coin.Picked. Статическое событие переживает все объекты, поэтому отпишись от него в OnDisable, иначе уничтоженный спавнер останется в его списке.

challenge icon

Задание

Средне

Пусть каждая волна ждёт, пока арена не опустеет.

  1. В Enemy добавь public static event Action<Enemy> Died; и вызови Died?.Invoke(this); непосредственно перед Destroy(gameObject);.
  2. В WaveSpawner веди подсчёт alive: увеличивай на 1 при каждом появлении, уменьшай на 1 в методе, который OnEnable подписывает на Enemy.Died, а OnDisable отписывает.
  3. После появления волны жди, пока alive > 0.

Нажми «Играть» и победи волну 1: волна 2 появится через 2 секунды. Затем нажми «Проверить».

Попробуйте сами

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

Все уроки раздела Архитектура игр в Unity

Потренируйтесь самостоятельно: Песочница Unity