ECS (Entity-Component-System) nedir?
ECS, oyun geliştirme gibi yazılım projelerinde sıklıkla kullanılan bir mimari desendir. Bu desen, veriyi (component) ve işlemi (system) birbirinden ayırarak daha modüler, esnek ve performanslı bir yazılım tasarımı sağlar. Oyunlar gibi dinamik ve büyük projelerde, karmaşık etkileşimleri yönetmek için güçlü bir yapıdır.
ECS Mimarisinin üç ana elamanı
Varlık (Entity)
Varlık, sistemdeki bir nesneyi temsil eder. Varlıklar genellikle benzersiz bir ID'ye sahip olup, bileşenleri (components) taşıyan yapılardır. Örneğin, bir oyuncu, düşman ya da ortamdaki herhangi bir obje birer varlık olabilir.
Bileşen (Component)
Bundan sonra Bileşenlere component
diye hitap edeceğim. varlıkların(Entity) özelliklerini tanımlar. Örneğin, bir "Sağlık" bileşeni, bir oyuncunun ne kadar sağlığa sahip olduğunu tutar. Bileşenler yalnızca veri taşır ve mantık içermez.
Sistem (System)
Sistemler, bileşenlere dayanarak işleyen mantıklardır. Örneğin, bir "Sağlık Sistemi", tüm varlıkların "Sağlık" bileşenlerini kontrol eder ve mantık işler. Bu sistemler, oyun dünyasında gerçekleşen işlemleri (hareket, saldırı, hasar alma) yönetir.
ECS kullanmanın avantajları
Performans:
ECS, veriyi bellekte ardışık şekilde düzenler, bu da daha hızlı işlem yapılmasına olanak tanır. Ayrıca, sistemler yalnızca gerekli bileşenlerle etkileşimde bulunur, bu da gereksiz işlemleri ortadan kaldırır.
HealthSystem sadece HealthComponentine sahip olan Entityler ve sadece HealthComponenti ile etkileşime giriyor.
Örnek vermek gerekirse;
Binlerce component içeren bir mmorpg karakterimiz var diyelim. Bütün herşeyi birden işlemek yerine. Health componenti ile ilgili görevleri sadece HealthSystem üstleniyor.
Modülerlik:
Bileşenler bağımsız olarak tasarlandığından, bir varlığa yeni özellikler eklemek veya bir sistemi değiştirmek oldukça basittir.
Bence ECS'nin asıl güçlü olduğu yer burası. Özellikle elimizde yeterince componentimiz olduğunda artık yap boz gibi component tak çıkar şeklinde yeni entityler yaratılabiliyor.
Burada bir düşman karakterim var. Hasar alıyor ama henüz ölemiyor. Bu karakterin ölebilmesi için tek yapılması gereken bu karaktere bir Health component'i eklemek.
Esneklik:
Sistemler birbirinden bağımsız olarak çalıştığından, yeni özellikler veya oyun mekanikleri eklemek daha kolaydır. Ayrıca, varlıklar farklı sistemler arasında geçiş yapabilir.
Karakterimizin Can'ı var dimi. Karakterimiz neden Fireball da atmasın diyorsak,Sadece Mana componenti gibi bir kaç component ekleyip fireball atacak hale getirebiliriz.
Kod üzerindede örneklemek gerekirse
Karakterimizin canı olsun birde yürüyebilsin istiyoruz dimi. Yapmamız gereken Karaktere Health ve Movement componenti vermek
public class Player : Entity
{
public HealthComponent Health { get; set; }
public MovementComponent Movement { get; set; }
}
buradada görüldüğü gibi componentler hiç bir mantıksal işlem yapmıyor, sadece veriyi tutuyor.
public class HealthComponent : Component
{
public int HealthPoints;
}
public class MovementComponent : Component
{
public Vector2 Velocity;
}
bu arkadaş da oyundaki bütün MovementComponent'i olan varlıkları kontrol ediyor
public class MovementSystem : System
{
public override void ProcessEntity(Entity entity)
{
var movement = entity.GetComponent<MovementComponent>();
var position = entity.GetComponent<PositionComponent>();
position.Position += movement.Velocity * delta;
}
}