Menu
CoddyTech

Dostosuj do siebie

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

Gra musi mieć zakończenie. Przegrywasz, gdy liczba żyć spadnie do 0, a wygrywasz, gdy wszystkie fale zostaną wysłane i na planszy nie pozostanie żaden przeciwnik. Spawner wie, kiedy wyruszy ostatnia fala, a Enemy.All wie, ilu przeciwników pozostało, więc spawner czeka, aż plansza będzie pusta, a następnie wywołuje zdarzenie, którego nasłuchuje GameManager. Korutyna czeka na spełnienie warunku za pomocą WaitUntil, które sprawdza lambdę raz na klatkę. Pokój zagadek, który otwiera wyjście, gdy wszystkie przełączniki są włączone:

yield return new WaitUntil(() => switchesOn == switches.Length);
exit.SetActive(true);

Każde z zakończeń wyświetla EndPanel z komunikatem i zatrzymuje grę za pomocą Time.timeScale = 0. Liczba żyć nigdy nie spada poniżej 0: czołg, który otrzyma obrażenia równe 2, gdy zostało mu 1 życie, ominąłby sprawdzenie, czy liczba wynosi dokładnie 0, więc Mathf.Max utrzymuje ją na poziomie 0 lub wyższym.

Przycisk Zagraj ponownie ponownie wczytuje scenę. Time.timeScale nie jest częścią sceny i zachowuje swoją wartość po jej wczytaniu, więc gra zatrzymana przy wartości 0 uruchomiłaby się ponownie w stanie zamrożenia: przed wczytaniem ustaw tę wartość z powrotem na 1.

Teraz nadaj grze własny charakter. Wszystko, co wpływa na jej balans, znajdziesz w Inspectorze:

  • GameManager gry: startMoney (150) i startLives (20).
  • waves obiektu Spawner: osiem wierszy z typem przeciwnika, liczbą i odstępami, oraz timeBetweenWaves (8).
  • Zasoby EnemyData: szybkość, zdrowie, nagroda i liczba żyć odbieranych przez dany typ przeciwnika. Boss ma 450 punktów zdrowia i odbiera 10 żyć.
  • Zasoby TowerData: koszt, obrażenia, zasięg, szybkostrzelność, wartości ulepszeń, obrażenia obszarowe działa Cannon oraz spowolnienie wieży Frost.

Z domyślnymi wartościami można wygrać, budując zróżnicowaną obronę na zakrętach ścieżki i ulepszając wieże w miarę zdobywania pieniędzy; kilka wież jednego typu nie wystarczy. Zmieniaj jedną wartość naraz i graj, by sprawdzić jej wpływ.

challenge icon

Wyzwanie

Trudny
  1. W WaveSpawner dodaj public event Action AllWavesCleared. Po wysłaniu ostatniej fali poczekaj, aż Enemy.All będzie pusta, a następnie wywołaj to zdarzenie.
  2. W GameManager dodaj serializowane pola endPanel (GameObject) i endText (TMP_Text). Liczba żyć nigdy nie spada poniżej 0, a gdy osiągnie 0, gra się kończy komunikatem Game Over. Gdy wszystkie fale zostaną pokonane i pozostaną życia, gra kończy się komunikatem You Win!. Zakończenie wyświetla panel z komunikatem i ustawia Time.timeScale na 0.
  3. Napisz public void PlayAgain(), którą wywołuje przycisk panelu: przywróć normalny czas i ponownie wczytaj aktywną scenę.

Naciśnij Play i broń bazy przez wszystkie osiem fal, a następnie kliknij Check. Potem dostosuj grę w Inspectorze i zagraj po swojemu.

Spróbuj swoich sił

using UnityEngine;
using TMPro;

public class GameManager : MonoBehaviour
{
    [SerializeField] private int startMoney = 100;
    [SerializeField] private int startLives = 20;
    [SerializeField] private WaveSpawner spawner;
    [SerializeField] private TMP_Text moneyText;
    [SerializeField] private TMP_Text livesText;
    [SerializeField] private TMP_Text waveText;

    private int money;
    private int lives;

    void OnEnable()
    {
        Enemy.ReachedBase += OnReachedBase;
        Enemy.Killed += OnKilled;
        spawner.WaveStarted += ShowWave;
    }

    void OnDisable()
    {
        Enemy.ReachedBase -= OnReachedBase;
        Enemy.Killed -= OnKilled;
        spawner.WaveStarted -= ShowWave;
    }

    void Start()
    {
        money = startMoney;
        lives = startLives;
        ShowMoney();
        ShowLives();
    }

    public bool TrySpend(int amount)
    {
        if (amount > money)
        {
            return false;
        }

        money -= amount;
        ShowMoney();
        return true;
    }

    public void Earn(int amount)
    {
        money += amount;
        ShowMoney();
    }

    void OnKilled(Enemy enemy)
    {
        Earn(enemy.data.reward);
    }

    void OnReachedBase(Enemy enemy)
    {
        lives -= enemy.data.damage;
        ShowLives();
    }

    void ShowMoney()
    {
        moneyText.text = "Money: " + money;
    }

    void ShowLives()
    {
        livesText.text = "Lives: " + lives;
    }

    void ShowWave(int wave, int total)
    {
        waveText.text = "Wave " + wave + "/" + total;
    }
}
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