Menu
CoddyTech

Despeja la arena

Parte de la sección Arquitectura de juegos en Unity del Journey de Unity de Coddy. Lección 55 de 64.

Un evento marcado como static pertenece a la clase, no a un objeto. Existe un único Enemy.Died para todos los enemigos que pueda haber, así que el spawner puede suscribirse con Enemy.Died += OnEnemyDied; antes de que exista ningún enemigo, y cada enemigo lo invoca pasándose a sí mismo como argumento. La misma idea en C# simple:

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;   // todavía no se necesita ningún Coin
    }

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

Se accede a un evento de instancia a través de un objeto, como en hero.Died; a uno estático, a través del nombre de la clase, como en Coin.Picked. Un evento estático sobrevive a todos los objetos, así que cancela la suscripción en OnDisable o un spawner destruido seguirá en su lista.

challenge icon

Desafío

Intermedio

Haz que cada oleada espere hasta que la arena esté despejada.

  1. En Enemy, añade public static event Action<Enemy> Died; y llama a Died?.Invoke(this); justo antes de Destroy(gameObject);.
  2. En WaveSpawner, lleva la cuenta de alive: añade 1 por cada aparición y resta 1 en un método que OnEnable agrega a Enemy.Died y que OnDisable elimina.
  3. Después de que aparezca una oleada, espera mientras alive > 0.

Pulsa «Jugar» y derrota la oleada 1: la oleada 2 llega 2 segundos después. Luego, pulsa «Comprobar».

Pruébalo tú mismo

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 las lecciones de Arquitectura de juegos en Unity

Practica por tu cuenta: Playground de Unity