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.
Wyzwanie
ŚredniUruchamiaj gotowe stany gracza za pomocą maszyny.
- W pliku
StateMachine.csnapiszpublic class StateMachinezpublic IState Current { get; private set; }oraz metodąTick(), która wykonuje tick stanu. ChangeState(IState next)ignoruje bieżący stan; w przeciwnym razie wywołuje Exit, ustawiaCurrenti wywołuje Enter.Player: Start tworzymachine,walkisneak, 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
1Komponenty, nie hierarchie
Małe komponentyBazowy skrypt przeciwnikaKomponenty abstrakcyjneWspółpracujące komponentyPowtórka: modułowa wieżyczkaPowtórka: podwójne działo4Dane serializowane
Klasy serializowalneListy w InspectorzeEnumy w InspectorzePodsumowanie: tabela łupówPodsumowanie: losowanie łupów7Maszyny stanów
Stany jako klasyStan alarmowyMaszyna stanówPrzejściaMózgi przeciwnikówAtaki rycerzaPodsumowanie: stany drzwi2Interfejsy w Unity
IDamageableInterfejsy i TryGetComponentGetComponentsPowtórka: klawisz interakcjiPowtórka: najbliższy w zasięgu5ScriptableObjects
Zasoby danychStatystyki broniWspółdzielone ustawieniaOcal wiatrFale jako danePowtórka: Baza przedmiotówPowtórka: Kupowanie w sklepie8Kod wielokrotnego użytku
Metody rozszerzająceGeneryczny singletonGeneryczne metody pomocniczePodsumowanie: FindNearestPoćwicz samodzielnie: Edytor online Unity