Menu
CoddyTech

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.

challenge icon

Görev

Orta

Oyuncunun hazır durumlarını bir makineyle çalıştır.

  1. StateMachine.cs içinde public class StateMachine sınıfını, public IState Current { get; private set; } özelliğini ve bu özelliği çalıştıran bir Tick() yöntemi yaz.
  2. ChangeState(IState next) geçerli durumla aynıysa hiçbir şey yapmaz; değilse Exit yöntemini çağırır, Current değerini ayarlar ve Enter yöntemini çağırır.
  3. Player: Start içinde machine, walk ve sneak oluş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

Kendi başına pratik yap: Unity playground