Menu
CoddyTech

Następna fala

Lekcja 17 z 18 w kursie Gra Unity: Obrona wieżowa w Coddy.

Między falami gracz buduje, a odliczanie pokazuje, ile czasu pozostało. Gracz, który jest gotowy, może przyciskiem wcześniej rozpocząć następną falę. Przerwa to pętla w korutynie, która zwraca null, więc działa raz na klatkę: odlicza pozostały czas, wyświetla go i kończy działanie, gdy czas się skończy lub gdy przycisk zażąda rozpoczęcia fali. Przycisk jedynie ustawia wartość boolowską, a pętla ją odczytuje:

while (left > 0f && !skipRequested)
{
    // wyświetl pozostałe sekundy, odliczaj w dół, poczekaj jedną klatkę
}
skipRequested = false;

Wartość boolowska jest ponownie ustawiana na false po użyciu, bo inaczej każda przerwa po pierwszej kończyłaby się natychmiast. Mathf.CeilToInt zaokrągla w górę, więc gdy pozostało 2.3 sekundy, wyświetlana jest wartość 3, a odliczanie pokazuje 1 przez całą ostatnią sekundę, zamiast 0. Odliczanie jest osobną korutyną, a yield return StartCoroutine(Countdown()); uruchamia ją i czeka na jej zakończenie, zanim pętla fal będzie kontynuowana.

HUD wyświetla również numer fali. Spawner go zna, a GameManager go wyświetla, więc spawner zgłasza zdarzenie C#, WaveStarted, wraz z falą i liczbą fal. W przeciwieństwie do statycznych zdarzeń wrogów należy ono do pojedynczego spawnera, a GameManager subskrybuje je za pośrednictwem pola spawner.

challenge icon

Wyzwanie

Trudny
  1. W WaveSpawner dodaj serializowane pola countdownText (obiekt TMP_Text) i nextWaveButton (obiekt GameObject), a także public void CallNextWave(), którą przycisk wywołuje, aby rozpocząć falę od razu.
  2. Zastąp oczekiwanie przed każdą falą odliczaniem uruchamianym przez yield return StartCoroutine(Countdown());. W trakcie odliczania przycisk jest widoczny, a tekst ma treść Next wave in 8 — liczba sekund pozostałych do końca, zaokrąglona w górę. Odliczanie kończy się, gdy upłynie czas lub ktoś kliknie przycisk; wtedy tekst jest pusty, a przycisk ukryty.
  3. Dodaj public event Action<int, int> WaveStarted, wywoływane z numerem fali (licząc od 1) i liczbą fal, gdy rozpoczyna się fala.
  4. W GameManager dodaj serializowane pola spawner (obiekt WaveSpawner) i waveText (obiekt TMP_Text), zasubskrybuj zdarzenie WaveStarted i wyświetl Wave 1/8.

HUD zawiera WaveText, CountdownText i NextWaveButton. Naciśnij Play, zbuduj obiekt i rozpocznij pierwszą falę wcześniej, a następnie naciśnij Check.

Spróbuj swoich sił

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");
    }
}
quiz iconSprawdź się

Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.

Wszystkie lekcje w sekcji Gra Unity: Obrona wieżowa