Menu
CoddyTech

Raggiungi la base

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

Un nemico che raggiunge l'ultimo waypoint è arrivato alla base: il giocatore perde vite e il nemico viene eliminato. Le vite appartengono a GameManager, che le mostra sullo schermo. Il nemico non dovrebbe aver bisogno di un riferimento a GameManager per segnalarlo: presto i nemici verranno creati a dozzine da un prefab, e un prefab non può puntare a un oggetto nella scena.

Un evento statico risolve entrambi i problemi. Appartiene alla classe Enemy, non a un singolo nemico, quindi GameManager si iscrive una volta e riceve le notifiche da ogni nemico, anche da quelli generati in seguito. Ogni nemico lo attiva passando se stesso come argomento, così il listener può leggere quale tipo è riuscito a passare. Una moneta in un platformer segnala allo stesso modo:

public class Coin : MonoBehaviour
{
    public static event Action<Coin> Collected;
    public int value = 1;

    void OnTriggerEnter(Collider other)
    {
        Collected?.Invoke(this);
        Destroy(gameObject);
    }
}
// ScoreBoard.cs
void OnEnable()
{
    Coin.Collected += AddCoin;
}

void OnDisable()
{
    Coin.Collected -= AddCoin;
}

void AddCoin(Coin coin)
{
    score += coin.value;
}

Un evento statico dura quanto il gioco, quindi -= è più importante che mai: un ScoreBoard distrutto, ma che non si è mai disiscritto, verrebbe comunque richiamato e il suo codice fallirebbe quando accede al testo distrutto. OnEnable e OnDisable vengono in coppia, quindi a ogni += corrisponde il suo -=.

challenge icon

Sfida

Facile

La base ha bisogno di vite e un nemico che la raggiunge deve sottrargliele.

  1. In EnemyData, aggiungi un int pubblico damage: il numero di vite che questo tipo di nemico sottrae alla base.
  2. In Enemy, dichiara un evento statico pubblico ReachedBase che passa il nemico (Action<Enemy>). Quando il nemico arriva all’ultimo waypoint, attivalo passandogli sé stesso e distruggi il nemico, invece di fermarti lì.
  3. In GameManager, aggiungi un int serializzato startLives (20) e un int privato lives che parte da quel valore. Iscriviti a Enemy.ReachedBase in OnEnable e annulla l’iscrizione in OnDisable. Ogni nemico che riesce a passare sottrae alle vite il valore damage della propria risorsa.
  4. Mostra le vite in un TMP_Text serializzato livesText, come Lives: 20, all’inizio e dopo ogni modifica.

L’oggetto Game ha il GameManager, nell’Inspector è collegato LivesText e entrambe le risorse sottraggono 1 vita. Premi Play, attendi che entrambi i nemici raggiungano la base, poi premi Check.

Provalo tu

using UnityEngine;

public class Enemy : MonoBehaviour
{
    public EnemyData data;
    public Transform[] waypoints;

    private int next = 1;
    private int health;

    void Awake()
    {
        health = data.maxHealth;
    }

    void Update()
    {
        if (next >= waypoints.Length)
        {
            return;
        }

        Vector3 target = waypoints[next].position;
        transform.position = Vector3.MoveTowards(transform.position, target, data.speed * Time.deltaTime);
        if (transform.position == target)
        {
            next++;
        }
    }
}
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