Menu
CoddyTech

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.

challenge icon

Görev

Orta

Gizlice 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.cs dosyasında, yalnızca makinenin ayarlayabileceği bir public Current özelliğine sahip, düz bir StateMachine sınıfı yaz. Eski durumun Exit metodunu, ardından yeni durumun Enter metodunu çalıştıran bir ChangeState(IState next) metodu ve geçerli durumun Tick metodunu çalıştıran bir Tick() 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.cs dosyasında machine adlı bir StateMachine alanı 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
quiz iconKendini test et

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