Menu
CoddyTech

Sınıflar Olarak Durumlar

Coddy'nin Unity Journey'sinin Unity'de Oyun Mimarisi bölümünün bir parçası. Ders 35 / 64.

3. bölümde enum üzerindeki switch, her durumun işini tek bir Update içinde tutar. Durumlar kendi verilerini taşımaya başladığında bu yaklaşım ölçeklenemez: yalnızca bir durumun kullandığı bir zamanlayıcı, MonoBehaviour içindeki bir alana dönüşür ve diğer tüm durumların alanlarının yanına eklenir; ayrıca her case, kullandığı değerleri sıfırlamayı unutmamalıdır. C#'taki durum deseni, her duruma kendi sınıfını verir ve her sınıf aynı arayüzü uygular. Bu yol işareti yanıp söner veya sürekli yanar; Space iki durum arasında geçiş yapar:

public interface IState
{
    void Enter();
    void Tick();
    void Exit();
}

public class BlinkState : IState
{
    private Renderer lamp;
    private float timer;

    public BlinkState(Renderer lamp)
    {
        this.lamp = lamp;
    }

    public void Enter() { timer = 0f; }

    public void Tick()
    {
        timer += Time.deltaTime;
        if (timer >= 0.5f)
        {
            timer = 0f;
            lamp.enabled = !lamp.enabled;
        }
    }

    public void Exit() { lamp.enabled = true; }
}

public class SteadyState : IState
{
    public void Enter() { }
    public void Tick() { }
    public void Exit() { }
}

public class Beacon : MonoBehaviour
{
    public Renderer lamp;
    private IState blink;
    private IState steady;
    private IState current;

    void Start()
    {
        blink = new BlinkState(lamp);
        steady = new SteadyState();
        SetState(steady);
    }

    void Update()
    {
        if (Keyboard.current.spaceKey.wasPressedThisFrame) SetState(current == steady ? blink : steady);
        current.Tick();
    }

    void SetState(IState next)
    {
        if (current != null) current.Exit();
        current = next;
        current.Enter();
    }
}

Durumlar MonoBehaviour değil, sıradan C# sınıflarıdır. Bunları new ile oluşturur ve ihtiyaç duydukları şeyleri kurucu aracılığıyla verirsin; burada bu, lambanın Renderer bileşenidir. Çünkü bunlar bileşen değildir ve GetComponent çağıramaz veya Inspector'da alan gösteremezler. Unity de yöntemlerini çağırmaz: MonoBehaviour olan Beacon'dır, bu nedenle Update her karede current.Tick() çağırır.

timer yalnızca BlinkState'e aittir ve Enter, işaret her yanıp sönmeye başladığında onu 0'a ayarlar. Exit, durum sona erdiğinde gerekli temizliği yapar: lamba kapalıyken Space'e basılabilir ve Exit lambayı yeniden yakar; böylece SteadyState hiçbir zaman karanlık bir lambayla başlamaz. SetState, önce eski durumun Exit yöntemini, ardından yeni durumun Enter yöntemini çalıştırır. Yavaş bir titreşim gibi üçüncü bir durum, bir sınıf daha eklemek demektir ve Beacon'ın Update yöntemi değişmez.

challenge icon

Görev

Orta

Taretin tarama durumunu yaz.

  1. IState.cs içinde, public interface IState arayüzünü void Enter();, void Tick(); ve void Exit(); ile tanımla.
  2. TurretStates.cs içinde, başı parametre olarak alan ScanState : IState sınıfını yaz. Enter: açı 0, baş Color.green. Tick: başın yerel y açısını -45 ile 45 arasında, saniyede 90 derece hızla döndür.
  3. Turret: Start içinde bir tanesini başlat, Update içinde tick metodunu çağır.

“Oyna” düğmesine bas: yeşil baş döner. Ardından “Kontrol et” düğmesine bas.

Kendin dene

using UnityEngine;

// ScanState

Unity'de Oyun Mimarisi bölümündeki tüm dersler

Kendi başına pratik yap: Unity playground