Uno script base per i nemici
Fa parte della sezione Architettura dei giochi in Unity del percorso Unity di Coddy. Lezione 2 di 50.
I nemici condividono gran parte del loro codice: punti vita, una velocità, un modo di muoversi. Quel codice può trovarsi in una classe base che deriva da MonoBehaviour, e ogni tipo di nemico deriva da essa. Questo Enemy imposta i suoi punti vita in Start e cammina nella direzione in cui è rivolto in Update, mentre un Ghost modifica Start per muoversi al doppio della velocità:
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 l'Inspector mostra maxHp e speed su un Ghost, ed eredita Update, quindi cammina 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, qualunque sia il loro livello di accesso, e chiama quello della classe più derivata. Se Start di Enemy fosse un void Start() private e Ghost ne dichiarasse uno proprio, Unity chiamerebbe solo quello di Ghost: quello di Enemy non verrebbe mai eseguito e hp resterebbe 0 senza alcun errore. Dichiarare i messaggi della classe base come protected virtual rende esplicito il normale funzionamento di 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 aggiungervisi.
Sfida
FacileI mostri marciano verso il castello. Enemy.cs contiene ciò che hanno in comune: Start imposta hp su maxHp e memorizza spawnPoint, mentre Update fa marciare il mostro lungo l’asse z alla velocità speed. Il Grunt è un Enemy semplice e funziona. Due tipi aggiungono un passaggio proprio, ma ognuno perde la parte di Enemy:
Golem: il suo Start rende il golem 1.5 volte più grande e registraThe golem wakes up, ma il suohprimane 0, perché Unity esegue lo Start di Golem e mai quello di Enemy.Wasp: il suo Update lo fa oscillare di 1 unità da un lato all’altro dispawnPoint.x, ma zigzaga sul posto, perché Unity esegue l’Update di Wasp e mai quello di Enemy.
Rendi lo Start e l’Update di Enemy protected virtual e sottoponili a override in Golem e Wasp, in modo che ciascuno esegua prima la parte di Enemy e poi la propria. Premi Play, poi Check.
Provalo tu
using UnityEngine;
// Ciò che accomuna tutti i mostri.
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()
{
// marcia verso il castello, lungo l'asse z
transform.position += Vector3.back * speed * Time.deltaTime;
}
}
Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.
Tutte le lezioni di Architettura dei giochi in Unity
1Componenti, non gerarchie
Componenti piccoliUno script base per i nemiciComponenti astrattiComponenti che collaboranoRiepilogo: torretta modulare4Dati serializzati
Classi serializzabiliListe nell'InspectorEnum nell'InspectorRiepilogo: tabella del bottino7Macchine a stati
Gli stati come classiUna macchina a statiTransizioniIntelligenze dei nemiciRiepilogo: stati della porta10Progetto: Sopravvissuto nell’arena
L’eroeTipi di nemici5ScriptableObjects
Asset di datiStatistiche delle armiImpostazioni condiviseOndate come datiRiepilogo: database degli oggetti