Menu
CoddyTech

Rendilo tuo

Lezione 18 di 18 del corso Gioco Unity: difesa della torre di Coddy.

Al gioco serve un finale. Si perde quando le vite raggiungono 0 e si vince quando sono state inviate tutte le ondate e non rimane alcun nemico sul tabellone. Lo spawner sa quando è uscita l'ultima ondata e Enemy.All sa quanti nemici restano, quindi lo spawner aspetta che il tabellone sia vuoto e poi genera un evento a cui ascolta il GameManager. Una coroutine aspetta una condizione con WaitUntil, che controlla una lambda una volta per frame. Una stanza rompicapo che apre l'uscita quando tutti gli interruttori sono attivi:

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

Entrambi i finali mostrano l'EndPanel con un messaggio e fermano il gioco con Time.timeScale = 0. Le vite non scendono mai sotto 0: un Tank che subisce 2 danni quando ne resta 1 salterebbe direttamente oltre un controllo di uguaglianza esatta a 0, quindi Mathf.Max le mantiene a 0 o più.

Rigioca ricarica la scena. Time.timeScale non fa parte della scena e mantiene il suo valore durante il caricamento, quindi una partita fermata a 0 ripartirebbe bloccata: riportalo a 1 prima di caricare.

Poi personalizza il gioco. Tutto ciò che ne bilancia il funzionamento si trova nell'Inspector:

  • Il GameManager del gioco: startMoney (150) e startLives (20).
  • Le waves dello Spawner: otto righe con nemico, quantità e distanza, e timeBetweenWaves (8).
  • Le risorse EnemyData: velocità, salute, ricompensa e vite sottratte da ciascun tipo. Il Boss ha 450 punti salute e ne sottrae 10.
  • Le risorse TowerData: costo, danni, gittata, cadenza di fuoco, valori dei potenziamenti, l'area d'effetto del Cannon e il rallentamento della torre Frost.

Con i valori predefiniti si può vincere con una difesa mista nelle curve del percorso, potenziata man mano che arrivano i soldi; poche torri dello stesso tipo non reggeranno. Modifica un valore alla volta e gioca per capire che effetto ha.

challenge icon

Sfida

Difficile
  1. In WaveSpawner, aggiungi public event Action AllWavesCleared. Dopo aver inviato l'ultima ondata, attendi finché Enemy.All non è vuoto, quindi solleva l'evento.
  2. In GameManager, aggiungi i campi serializzati endPanel (un GameObject) e endText (un TMP_Text). Le vite non scendono mai sotto 0 e, quando raggiungono 0, la partita termina con Game Over. Quando tutte le ondate sono state completate e restano vite, la partita termina con You Win!. Al termine viene mostrato il pannello con il messaggio e Time.timeScale viene impostato a 0.
  3. Scrivi public void PlayAgain(), richiamato dal pulsante del pannello: ripristina il normale scorrere del tempo e carica di nuovo la scena attiva.

Premi Play e difendi la base per tutte e otto le ondate, poi premi Check. Dopodiché, regola il gioco nell'Inspector e giocaci a modo tuo.

Provalo tu

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 iconMettiti alla prova

Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.

Tutte le lezioni di Gioco Unity: difesa della torre