Menu
CoddyTech

Uno script base per i nemici

Fa parte della sezione Architettura dei giochi in Unity del percorso Unity di Coddy. Lezione 2 di 64.

In C#, una classe può derivare da un'altra: class Ghost : Enemy ottiene tutti i campi e i metodi di Enemy e ne aggiunge di propri. Un metodo che la classe base contrassegna come virtual può essere sostituito nella sottoclasse con override, e base.Describe() esegue la versione della classe base dall'interno del nuovo metodo. In C# semplice:

class Enemy
{
    protected int hp = 3;

    public virtual string Describe()
    {
        return "Enemy with " + hp + " hp";
    }
}

class Ghost : Enemy
{
    public override string Describe()
    {
        return base.Describe() + ", see-through";
    }
}

Il metodo Describe() di Ghost restituisce Enemy with 3 hp, see-through. protected significa che Enemy e le sue sottoclassi possono usare hp, mentre le altre classi non possono farlo.

In Unity, i nemici condividono gran parte del codice: punti vita, velocità e un modo per muoversi. Questo codice si trova in una classe base che deriva da MonoBehaviour, e ogni tipo di nemico deriva da essa. Questa classe Enemy imposta i punti vita in Start e si muove nella direzione verso cui è rivolta in Update, mentre Ghost modifica l'avvio per muoversi a velocità doppia:

public class Enemy : MonoBehaviour
{
    public int maxHp = 3;
    public float speed = 2f;
    protected int hp;

    protected virtual void Start()
    {
        hp = maxHp;
    }

    protected virtual void Update()
    {
        transform.Translate(Vector3.forward * speed * Time.deltaTime);
    }
}
public class Ghost : Enemy
{
    protected override void Start()
    {
        base.Start();
        speed *= 2f;
    }
}

Ghost eredita i campi, quindi nell'Inspector vengono mostrati maxHp e speed per un Ghost; inoltre eredita Update, quindi si muove senza avere un proprio Update. hp è protected: Enemy e le sue sottoclassi possono usarlo, gli altri script no.

Unity individua Start e Update in base al nome, indipendentemente dal loro livello di accesso, e chiama quello della classe più derivata. Se lo Start di Enemy fosse un void Start() privato e Ghost ne dichiarasse uno proprio, Unity chiamerebbe solo quello di Ghost: quello di Enemy non verrebbe mai eseguito e hp resterebbe a 0, senza alcun errore. Dichiarare i metodi della classe base protected virtual rende esplicito questo comportamento in C#: la sottoclasse scrive override e base.Start() esegue la parte della classe base nel punto in cui lo chiami. Se ometti la chiamata, la parte della classe base viene saltata: è così che una sottoclasse sostituisce un passaggio invece di aggiungervi qualcosa.

challenge icon

Sfida

Facile

Fai in modo che Golem e Wasp eseguano la parte di Enemy prima della propria.

  1. In Enemy, scrivi protected virtual davanti a void Start() e void Update().
  2. In Golem, impostalo come protected override void Start() con base.Start(); come prima riga.
  3. In Wasp, impostalo come protected override void Update() con base.Update(); come prima riga.

Premi «Gioca»: il golem avanza con gli hp al massimo e la vespa zigzaga mentre avanza. Poi premi «Verifica».

Provalo tu

using UnityEngine;

// Ciò che tutti i mostri hanno in comune.
public class Enemy : MonoBehaviour
{
    public int maxHp = 4;
    public float speed = 1.5f;

    protected int hp;
    protected Vector3 spawnPoint;

    void Start()
    {
        hp = maxHp;
        spawnPoint = transform.position;
    }

    void Update()
    {
        // avanza verso il castello lungo l'asse z
        transform.position += Vector3.back * speed * Time.deltaTime;
    }
}

Tutte le lezioni di Architettura dei giochi in Unity

Esercitati da solo: Playground Unity