Siguiente oleada
Lección 17 de 18 del curso Juego de Unity: defensa de torres de Coddy.
Entre oleadas, el jugador construye y una cuenta regresiva muestra cuánto tiempo queda. Un jugador que esté listo puede iniciar la siguiente oleada antes de tiempo con un botón. La pausa es un bucle en una corrutina que cede null, por lo que se ejecuta una vez por fotograma: cuenta el tiempo restante, lo muestra y termina cuando se acaba el tiempo o cuando se pulsa el botón para iniciar la oleada. El botón solo establece un bool y el bucle lo lee:
while (left > 0f && !skipRequested)
{
// muestra los segundos restantes, haz la cuenta atrás, espera un fotograma
}
skipRequested = false;El bool se vuelve a establecer en false después de haberse usado; de lo contrario, todas las pausas posteriores a la primera terminarían de inmediato. Mathf.CeilToInt redondea hacia arriba, así que si quedan 2.3 segundos, se muestra 3, y la cuenta regresiva indica 1 durante todo el último segundo en vez de 0. La cuenta regresiva es una corrutina propia, y yield return StartCoroutine(Countdown()); la ejecuta y espera a que termine antes de que continúe el bucle de oleadas.
El HUD también muestra el número de oleada. El spawner lo conoce y GameManager lo muestra, así que el spawner lanza un evento de C#, WaveStarted, con la oleada y el número de oleadas. A diferencia de los eventos estáticos de los enemigos, pertenece a un único spawner, y GameManager se suscribe a través de su campo spawner.
Desafío
Difícil- En
WaveSpawner, añade los campos serializadoscountdownText(un TMP_Text) ynextWaveButton(un GameObject), ypublic void CallNextWave(), que el botón llama para solicitar que la oleada empiece ahora. - Reemplaza la espera antes de cada oleada por una cuenta regresiva, ejecutada con
yield return StartCoroutine(Countdown());. Mientras se ejecuta, el botón se muestra y el texto indicaNext wave in 8, los segundos restantes redondeados hacia arriba. Termina cuando se acaba el tiempo o se hace clic en el botón; después, el texto queda vacío y el botón se oculta. - Añade
public event Action<int, int> WaveStarted, que se activa con el número de la oleada (a partir de 1) y el número de oleadas cuando empieza una oleada. - En
GameManager, añade los campos serializadosspawner(un WaveSpawner) ywaveText(un TMP_Text), suscríbete a WaveStarted y muestraWave 1/8.
El HUD tiene WaveText, CountdownText y NextWaveButton. Pulsa Play, construye y llama a la primera oleada antes de tiempo; después, pulsa Check.
Pruébalo tú mismo
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class WaveSpawner : MonoBehaviour
{
[SerializeField] private List<Wave> waves = new List<Wave>();
[SerializeField] private Transform[] waypoints;
[SerializeField] private float timeBetweenWaves = 5f;
void Start()
{
StartCoroutine(RunWaves());
}
IEnumerator RunWaves()
{
for (int i = 0; i < waves.Count; i++)
{
yield return new WaitForSeconds(timeBetweenWaves);
Debug.Log("Wave " + (i + 1));
Wave wave = waves[i];
for (int n = 0; n < wave.count; n++)
{
Enemy enemy = Instantiate(wave.enemy, waypoints[0].position, Quaternion.identity);
enemy.waypoints = waypoints;
yield return new WaitForSeconds(wave.spacing);
}
}
Debug.Log("All waves sent");
}
}
Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.