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.
Görev
OrtaTaretin tarama durumunu yaz.
IState.csiçinde,public interface IStatearayüzünüvoid Enter();,void Tick();vevoid Exit();ile tanımla.TurretStates.csiçinde, başı parametre olarak alanScanState : IStatesınıfını yaz. Enter: açı 0, başColor.green. Tick: başın yerel y açısını-45ile45arasında, saniyede90derece hızla döndür.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
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