Bir Durum Makinesi
Coddy'nin Unity Journey'sinin Unity'de Oyun Mimarisi bölümünün bir parçası. Ders 37 / 64.
Beacon'ın SetState yöntemi, durumları olan her nesnede aynı olurdu: bir taret, bir düşman, bir kapı. Bu kod, mevcut durumu tutan ve değiştiren durum makinesi adlı ayrı bir sınıfta yer alabilir. Her nesne kodu tekrarlamak yerine bir makine oluşturur ve onu çağırır:
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();
}
}İlk ChangeState çağrısında çıkılacak bir durum yoktur: Current null'dır ve ?., Exit çağrısını atlar. Bölüm 1'de ?. işleç biçiminin Unity'nin sahte null değerini yakalayamadığı konusunda uyarılmıştın; bu, yok edilmiş Unity Objects için geçerlidir. Durumlar sıradan C# nesneleri olduğundan burada ?. güvenlidir. Current özelliğinin private set erişimcisi vardır; bu nedenle hiçbir betik, ChangeState'i ve onun Exit ile Enter çağrılarını kullanmadan durumu değiştiremez.
İki durum aynı şeye dokunduğunda ChangeState içindeki sıralama önemlidir. Önce Exit eski durumun yaptığı değişikliği geri alır, ardından Enter yeni durumu ayarlar; böylece son sözü yeni durum söyler. DarkState'in Enter yöntemi lambayı kapatıp BlinkState'in Exit yönteminden önce çalışsaydı, Exit lambayı tekrar yakarak karanlık durumunu bozardı. StateMachine de sıradan bir sınıftır: işaret feneri, taret ve düşman, her biri new ile kendine ait bir makine oluşturur ve kendi Update yönteminden makinenin Tick yöntemini çağırır.
Görev
OrtaOyuncunun hazır durumlarını bir makineyle çalıştır.
StateMachine.csiçindepublic class StateMachinesınıfını,public IState Current { get; private set; }özelliğini ve bu özelliği çalıştıran birTick()yöntemi yaz.ChangeState(IState next)geçerli durumla aynıysa hiçbir şey yapmaz; değilse Exit yöntemini çağırır,Currentdeğerini ayarlar ve Enter yöntemini çağırır.Player: Start içindemachine,walkvesneakoluşturulur ve yürünür; Update içinde Space basılı tutulurken gizlice hareket edilir, aksi durumda yürünür ve ardından durum çalıştırılır.
“Oyna” düğmesine bas ve Space tuşunu basılı tut: Sneak: enter. Ardından “Kontrol et” düğmesine bas.
Kendin dene
// StateMachine: Current, ChangeState ve Tick
Unity'de Oyun Mimarisi bölümündeki tüm dersler
1Kalıtım Değil, Bileşenler
Küçük BileşenlerTemel Düşman Script'iSoyut BileşenlerBirlikte Çalışan BileşenlerTekrar: Modüler TaretTekrar: Çift Namlulu Top4Serileştirilmiş Veriler
Serileştirilebilir SınıflarInspector'da ListelerInspector'da Enum'larTekrar: Ganimet TablosuTekrar: Ganimeti At7Durum Makineleri
Sınıflar Olarak DurumlarAlarm DurumuBir Durum MakinesiGeçişlerDüşmanların Yapay ZekâsıŞövalye SaldırıyorÖzet: Kapı Durumları2Unity'de Arayüzler
IDamageableArayüzler ve TryGetComponentGetComponentsÖzet: Etkileşim TuşuÖzet: Erişim Mesafesindeki En Yakın5ScriptableObjects
Veri VarlıklarıSilah İstatistikleriOrtak AyarlarRüzgârı KaydetVeri Olarak DalgalarTekrar: Eşya VeritabanıTekrar: Dükkândan Satın Al8Yeniden Kullanılabilir Kod
Genişletme MetotlarıGeneric SingletonGeneric YardımcılarTekrar: FindNearestKendi başına pratik yap: Unity playground