Menu
CoddyTech

Maszyna stanów

Część sekcji Architektura gier w Unity ścieżki Unity w Coddy. Lekcja 37 z 64.

Metoda SetState obiektu Beacon byłaby taka sama w każdym obiekcie ze stanami: wieżyczce, przeciwniku czy drzwiach. Ten kod może znajdować się we własnej klasie — maszynie stanów, która przechowuje bieżący stan i go zmienia. Każdy obiekt tworzy jedną maszynę i z niej korzysta, zamiast powtarzać kod:

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();
    }
}

Pierwsze wywołanie ChangeState nie ma stanu, z którego mogłoby wyjść: Current ma wartość null, a ?. pomija wywołanie Exit. W sekcji 1 ostrzegaliśmy, że ?. nie wykrywa fałszywego null w Unity; dotyczy to zniszczonych obiektów Unity, a stany są zwykłymi obiektami C#, więc ?. jest tu bezpieczne. Current ma private set, więc żaden skrypt nie może zmienić stanu bez użycia ChangeState i jego Exit oraz Enter.

Kolejność wewnątrz ChangeState ma znaczenie zawsze wtedy, gdy dwa stany wpływają na tę samą rzecz. Exit cofa zmiany wprowadzone przez stary stan, a następnie Enter konfiguruje nowy, dzięki czemu ostatnie słowo należy do nowego stanu. Gdyby Enter obiektu DarkState wyłączało lampę i wykonywało się przed Exit obiektu BlinkState, to Exit ponownie włączyłoby lampę w ciemnym stanie. StateMachine również jest zwykłą klasą: obiekt Beacon, wieżyczka i przeciwnik tworzą własne maszyny za pomocą new i wywołują ich Tick z metody Update.

challenge icon

Wyzwanie

Średni

Uruchamiaj gotowe stany gracza za pomocą maszyny.

  1. W pliku StateMachine.cs napisz public class StateMachine z public IState Current { get; private set; } oraz metodą Tick(), która wykonuje tick stanu.
  2. ChangeState(IState next) ignoruje bieżący stan; w przeciwnym razie wywołuje Exit, ustawia Current i wywołuje Enter.
  3. Player: Start tworzy machine, walk i sneak, a następnie przechodzi do chodzenia; Update przechodzi do skradania, gdy spacja jest wciśnięta, w przeciwnym razie do chodzenia, a potem wykonuje tick.

Naciśnij „Graj” i przytrzymaj spację: Sneak: enter. Następnie naciśnij „Sprawdź”.

Spróbuj swoich sił

// StateMachine: Current, ChangeState i Tick

Wszystkie lekcje w sekcji Architektura gier w Unity

Poćwicz samodzielnie: Edytor online Unity