Bir Durum Makinesi
Coddy'nin Unity Journey'sinin Unity'de Oyun Mimarisi bölümünün bir parçası. Ders 29 / 50.
İşaret Feneri'nin 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ı kendi sınıfında 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 ?. operatörünün Unity'nin sahte null değerini yakalayamadığı konusunda uyarıda bulunulmuştu; bu, yok edilmiş Unity nesneleriyle ilgilidir ve durumlar düz C# nesneleri olduğundan burada ?. güvenlidir. Current bir private set özelliğine sahiptir; dolayısıyla 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. Exit, eski durumun değiştirdiklerini geri alır, ardından Enter yeni durumu kurar; 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ı karanlık durumda tekrar yakardı. StateMachine de düz bir sınıftır: işaret feneri, bir taret ve bir düşman her biri new ile kendi örneğini oluşturur ve Update yöntemlerinden Tick'i çağırır.
Görev
OrtaGizlice hareket etmek için Space tuşunu basılı tut. WalkState ve SneakState, PlayerStates.cs dosyasında hazır: Enter ve Exit metotları olanları kaydeder (Walk: enter, Sneak: exit...), Tick metotları ise oyuncunun Move() metodunu çağırır. Bunları çalıştıran makineyi yaz.
StateMachine.csdosyasında, yalnızca makinenin ayarlayabileceği bir publicCurrentözelliğine sahip, düz birStateMachinesınıfı yaz. Eski durumun Exit metodunu, ardından yeni durumun Enter metodunu çalıştıran birChangeState(IState next)metodu ve geçerli durumun Tick metodunu çalıştıran birTick()metodu ekle.- Oyuncu her karede durumunu sorduğundan, zaten geçerli olan durumla
ChangeStateçağrıldığında hiçbir şey olmaz: ne Exit ne de Enter çalışır. Player.csdosyasındamachineadlı birStateMachinealanı ekle. Start içinde makineyi ve her biri oyuncuyu alan iki durumu oluştur ve yürümeyle başla. Update içinde Space basılı tutulurken gizlice hareket etmeye, aksi durumda yürümeye geç; ardından makineyi tick et.
Play'e bas, yürü, Space tuşunu basılı tutup yürümeye devam et, ardından Check'e bas.
Kendin dene
// StateMachine: Current, ChangeState ve Tick
Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.
Unity'de Oyun Mimarisi bölümündeki tüm dersler
1Hiyerarşiler Değil, Bileşenler
Küçük BileşenlerTemel Bir Düşman BetiğiSoyut BileşenlerBirlikte Çalışan BileşenlerÖzet: Modüler Taret4Serileştirilmiş Veriler
Serileştirilebilir SınıflarInspector'da ListelerInspector'da Enum'larÖzet: Ganimet Tablosu7Durum Makineleri
Sınıflar Olarak DurumlarBir Durum MakinesiGeçişlerDüşmanların Yapay ZekâsıTekrar: Kapı Durumları10Proje: Arena Hayatta Kalma
KahramanDüşman Türleri5ScriptableObjects
Veri VarlıklarıSilah İstatistikleriPaylaşılan AyarlarVeri Olarak DalgalarTekrar: Eşya Veritabanı8Yeniden Kullanılabilir Kod
Genişletme MetotlarıGeneric SingletonGeneric YardımcılarTekrar: FindNearest