Menu
CoddyTech

Limpe a Arena

Parte da seção Arquitetura de Jogos no Unity do Journey de Unity da Coddy. Lição 55 de 64.

Um evento marcado como static pertence à classe, não a um objeto. Existe um Enemy.Died para cada inimigo que vier a existir, então o spawner pode se inscrever com Enemy.Died += OnEnemyDied; antes de qualquer inimigo existir, e cada inimigo o aciona passando a si mesmo como argumento. A mesma ideia em C# puro:

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;   // ainda não é necessário nenhum Coin
    }

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

Um evento de instância é acessado por meio de um objeto, como hero.Died; um evento estático, por meio do nome da classe, como Coin.Picked. Um evento estático sobrevive a todos os objetos, então cancele a inscrição em OnDisable, ou um spawner destruído continuará na lista.

challenge icon

Desafio

Médio

Faça cada onda esperar até a arena estar vazia.

  1. Em Enemy, adicione public static event Action<Enemy> Died; e chame Died?.Invoke(this); logo antes de Destroy(gameObject);.
  2. Em WaveSpawner, conte alive: some 1 a cada surgimento e subtraia 1 em um método que OnEnable adiciona a Enemy.Died e que OnDisable remove.
  3. Depois que uma onda surgir, espere enquanto alive > 0.

Pressione “Jogar” e derrote a onda 1: a onda 2 chega 2 segundos depois. Em seguida, pressione “Verificar”.

Experimente você mesmo

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

Todas as lições de Arquitetura de Jogos no Unity

Pratique por conta própria: Playground de Unity