Una macchina a stati
Fa parte della sezione Architettura dei giochi in Unity del percorso Unity di Coddy. Lezione 37 di 64.
Il metodo SetState del Faro sarebbe uguale in ogni oggetto con stati: una torretta, un nemico, una porta. Quel codice può stare in una classe a sé, una macchina a stati, che conserva lo stato corrente e lo cambia. Ogni oggetto crea una macchina e la chiama, invece di ripetere il codice:
public class StateMachine
{
public IState Current { get; private set; }
public void ChangeState(IState next)
{
Current?.Exit();
Current = next;
Current.Enter();
}
public void Tick()
{
Current?.Tick();
}
}
public class Beacon : MonoBehaviour
{
public Renderer lamp;
private StateMachine machine = new StateMachine();
private IState blink;
private IState steady;
void Start()
{
blink = new BlinkState(lamp);
steady = new SteadyState();
machine.ChangeState(steady);
}
void Update()
{
if (Keyboard.current.spaceKey.wasPressedThisFrame) machine.ChangeState(machine.Current == steady ? blink : steady);
machine.Tick();
}
}La prima chiamata a ChangeState non ha uno stato da cui uscire: Current è null e ?. salta la chiamata a Exit. La sezione 1 avvertiva che ?. non rileva il null fittizio di Unity; questo riguarda gli oggetti Unity distrutti, mentre gli stati sono normali oggetti C#, quindi ?. è sicuro qui. Current ha un private set, quindi nessuno script può sostituire lo stato senza passare da ChangeState e dai suoi metodi Exit ed Enter.
L'ordine all'interno di ChangeState è importante ogni volta che due stati modificano la stessa cosa. Exit annulla ciò che ha modificato il vecchio stato, poi Enter configura quello nuovo, così l'ultimo a intervenire è il nuovo stato. Se il metodo Enter di DarkState spegnesse la lampada e venisse eseguito prima di Exit di BlinkState, quest'ultimo riaccenderebbe la lampada mentre è attivo lo stato buio. Anche StateMachine è una normale classe: il faro, una torretta e un nemico ne creano ciascuno una con new e ne chiamano Tick dal proprio Update.
Sfida
MedioEsegui gli stati pronti del giocatore con una macchina.
- In
StateMachine.cs, scrivipublic class StateMachineconpublic IState Current { get; private set; }e unTick()che esegua il tick dello stato. ChangeState(IState next)ignora lo stato corrente; altrimenti, esegue Exit, impostaCurrented esegue Enter.Player: Start creamachine,walk,sneake cammina; Update esegue sneak mentre tieni premuto Space, altrimenti cammina, poi esegue il tick.
Premi «Gioca» e tieni premuto Space: Sneak: enter. Poi premi «Verifica».
Provalo tu
// StateMachine: Current, ChangeState e Tick
Tutte le lezioni di Architettura dei giochi in Unity
1Componenti, non gerarchie
Componenti piccoliUno script base per i nemiciComponenti astrattiComponenti che collaboranoRipasso: torretta modulareRipasso: cannone doppio4Dati serializzati
Classi serializzabiliElenchi nell'InspectorEnum nell'InspectorRiepilogo: tabella del bottinoRiepilogo: tira il bottino7Macchine a stati
Gli stati come classiLo stato di allertaUna macchina a statiTransizioniIntelligenza dei nemiciIl cavaliere attaccaRiepilogo: stati delle porte2Interfacce in Unity
IDamageableInterfacce e TryGetComponentGetComponentsRiepilogo: tasto InteragisciRiepilogo: il più vicino a portata5ScriptableObjects
Asset di datiStatistiche delle armiImpostazioni condiviseSalva il ventoOnde come datiRiepilogo: database degli oggettiRiepilogo: comprare dal negozioEsercitati da solo: Playground Unity