Przejścia
Część sekcji Architektura gier w Unity ścieżki Unity w Coddy. Lekcja 38 z 64.
Kto decyduje o zmianie stanu? Powierzenie tego właścicielowi sprawia, że wszystkie reguły znów trafiają do jednej metody Update, tak jak w przypadku instrukcji switch. Zwykle przyjmuje się, że każdy stan zna własne wyjście: w swojej metodzie Tick sprawdza warunek i prosi maszynę o przejście do następnego stanu. Ta bomba czeka, aż gracz się zbliży, a potem zaczyna palić lont i wraca do oczekiwania, jeśli gracz ucieknie:
public class Bomb : MonoBehaviour
{
public Transform player;
public StateMachine machine = new StateMachine();
public IState idle;
public IState fuse;
void Start()
{
idle = new IdleState(this);
fuse = new FuseState(this);
machine.ChangeState(idle);
}
void Update() { machine.Tick(); }
public bool PlayerNear()
{
return Vector3.Distance(transform.position, player.position) < 3f;
}
}
public class IdleState : IState
{
private Bomb bomb;
public IdleState(Bomb bomb) { this.bomb = bomb; }
public void Enter() { }
public void Exit() { }
public void Tick()
{
if (bomb.PlayerNear()) bomb.machine.ChangeState(bomb.fuse);
}
}
public class FuseState : IState
{
private Bomb bomb;
private float timer;
public FuseState(Bomb bomb) { this.bomb = bomb; }
public void Enter() { timer = 2f; }
public void Exit() { }
public void Tick()
{
if (!bomb.PlayerNear())
{
bomb.machine.ChangeState(bomb.idle);
return;
}
timer -= Time.deltaTime;
if (timer <= 0f)
{
Debug.Log("Boom!");
Object.Destroy(bomb.gameObject);
}
}
}Każdy stan otrzymuje bombę w konstruktorze i za jej pośrednictwem uzyskuje dostęp do maszyny, sprawdzania, czy gracz jest blisko, oraz pozostałych stanów. Bomba tworzy każdy stan raz, w metodzie Start, więc stan nigdy nie tworzy innego za pomocą new: dwa stany, które tworzyłyby się nawzajem w swoich konstruktorach, zapętliłyby się, aż do przepełnienia stosu. Metoda Update bomby jedynie wykonuje Tick maszyny, a reguły znajdują się w stanach, do których należą: lont palący się przez 2 sekundy to wyłącznie sprawa FuseState.
ChangeState uruchamia Exit stanu FuseState i Enter stanu IdleState, ale pozostała część metody Tick stanu FuseState nadal wykonałaby się po tym wywołaniu. return ją zatrzymuje; w przeciwnym razie lont paliłby się jeszcze przez jedną klatkę, mimo że stan już się zakończył. Zapis Destroy ma postać Object.Destroy: MonoBehaviour dziedziczy tę metodę po klasie Object z Unity, a zwykła klasa musi podać nazwę klasy.
Wyzwanie
ŚredniZapisz przejścia pułapki na muchy w każdym wywołaniu Tick w pliku FlytrapStates.cs.
- Otwarta: gdy
trap.PlayerInReach(), wywołajtrap.machine.ChangeState(trap.snap);. - Kłapnięcie: dodawaj
Time.deltaTimedotimer; po osiągnięciu0.5przejdź dotrap.chew, jeśli gracz nadal jest w zasięgu, w przeciwnym razie dotrap.open. - Żucie: odliczaj
timerod 3; po osiągnięciu 0 przejdź dotrap.open.
Naciśnij „Graj”, wejdź w pułapkę, a potem jej uniknij. Następnie naciśnij „Sprawdź”.
Spróbuj swoich sił
using UnityEngine;
public class OpenState : IState
{
private Flytrap trap;
public OpenState(Flytrap trap)
{
this.trap = trap;
}
public void Enter()
{
trap.Paint(new Color(0.3f, 0.8f, 0.2f));
}
public void Tick()
{
// Zatrzaśnij się, gdy gracz znajdzie się w zasięgu
}
public void Exit()
{
}
}
public class SnapState : IState
{
private Flytrap trap;
private float timer;
public SnapState(Flytrap trap)
{
this.trap = trap;
}
public void Enter()
{
timer = 0f;
trap.Paint(new Color(1f, 0.55f, 0.1f));
}
public void Tick()
{
// Po 0.5 sekundy: żuj, jeśli gracz nadal jest w zasięgu; w przeciwnym razie otwórz się ponownie
}
public void Exit()
{
}
}
public class ChewState : IState
{
private Flytrap trap;
private float timer;
public ChewState(Flytrap trap)
{
this.trap = trap;
}
public void Enter()
{
timer = 3f;
trap.Paint(new Color(0.5f, 0.05f, 0.1f));
Debug.Log("Chomp!");
}
public void Tick()
{
// Po 3 sekundach: otwórz się ponownie
}
public void Exit()
{
}
}
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ów2Interfejsy 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