Gli stati come classi
Fa parte della sezione Architettura dei giochi in Unity del percorso Unity di Coddy. Lezione 28 di 50.
La gestione degli stati tramite switch della sezione 3 concentra il lavoro di ogni stato in un unico Update. Questa soluzione non è scalabile quando gli stati hanno dati propri: un timer usato da un solo stato finisce per essere un campo di MonoBehaviour, accanto ai campi di tutti gli altri stati, e ogni caso deve ricordarsi di reimpostare ciò che usa. Il pattern state di C# assegna a ogni stato una classe propria e ogni classe implementa un'interfaccia. Questo segnalatore stradale lampeggia o resta acceso, e Space alterna i due stati:
public interface IState
{
void Enter();
void Tick();
void Exit();
}
public class BlinkState : IState
{
private Renderer lamp;
private float timer;
public BlinkState(Renderer lamp)
{
this.lamp = lamp;
}
public void Enter() { timer = 0f; }
public void Tick()
{
timer += Time.deltaTime;
if (timer >= 0.5f)
{
timer = 0f;
lamp.enabled = !lamp.enabled;
}
}
public void Exit() { lamp.enabled = true; }
}
public class SteadyState : IState
{
public void Enter() { }
public void Tick() { }
public void Exit() { }
}
public class Beacon : MonoBehaviour
{
public Renderer lamp;
private IState blink;
private IState steady;
private IState current;
void Start()
{
blink = new BlinkState(lamp);
steady = new SteadyState();
SetState(steady);
}
void Update()
{
if (Keyboard.current.spaceKey.wasPressedThisFrame) SetState(current == steady ? blink : steady);
current.Tick();
}
void SetState(IState next)
{
if (current != null) current.Exit();
current = next;
current.Enter();
}
}Gli stati sono normali classi C#, non MonoBehaviours. Li crei con new e gli passi ciò di cui hanno bisogno tramite il costruttore, qui il Renderer della lampada, perché non sono componenti e non possono chiamare GetComponent né mostrare campi nell'Inspector. Neanche Unity chiama i loro metodi: Beacon è il MonoBehaviour, quindi il suo Update chiama current.Tick() a ogni frame.
Il timer appartiene solo a BlinkState e il suo Enter lo imposta a 0 ogni volta che il segnalatore inizia a lampeggiare. Exit sistema le cose quando lo stato termina: Space può essere premuto mentre la lampada è spenta, e Exit la riaccende, così SteadyState non inizia mai con la lampada spenta. SetState esegue Exit dello stato precedente, poi Enter del nuovo stato. Un terzo stato, come un impulso lento, è un'altra classe, e Update di Beacon non cambia.
Sfida
MedioUna torretta di guardia protegge il cortile. Le frecce guidano il Player (pronto). Assegna alla torretta due stati, scritti come classi:
- In
IState.cs, dichiarapublic interface IStateconvoid Enter(),void Tick()evoid Exit(). - In
TurretStates.cs, scrivi due classi semplici che lo implementano.ScanStatericeve la testa della torretta nel costruttore. Fa oscillare la testa da un lato all'altro: l'angolo y locale della testa si sposta a 90 gradi al secondo tra-45e45, partendo da 0 e girando verso l'alto ogni volta che inizia la scansione. Anche il suo Enter colora la testa conColor.green. AlertStatericeve la testa e il giocatore. Il suo Enter colora la testa conColor.rede registraIntruder!; il suo Tick gira la testa per rivolgerla verso il giocatore solo attorno all'asse y, senza inclinazione; il suo Exit registraAll clear.- In
Turret.cs, crea entrambi gli stati in Start e avvia la scansione. A ogni fotogramma, passa allo stato di allerta quando il giocatore è più vicino dirange(4) alla torretta, e torna alla scansione quando non lo è, quindi esegui il Tick dello stato corrente. Un cambio esegue l'Exit del vecchio stato, quindi l'Enter del nuovo.
Premi Play, avvicinati alla torretta e poi allontanati, quindi premi Check.
Provalo tu
using UnityEngine;
// ScanState e AlertState
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