Menu
CoddyTech

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.

challenge icon

Sfida

Medio

Esegui gli stati pronti del giocatore con una macchina.

  1. In StateMachine.cs, scrivi public class StateMachine con public IState Current { get; private set; } e un Tick() che esegua il tick dello stato.
  2. ChangeState(IState next) ignora lo stato corrente; altrimenti, esegue Exit, imposta Current ed esegue Enter.
  3. Player: Start crea machine, walk, sneak e 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

Esercitati da solo: Playground Unity