ECS是Entity-Component-System的缩写,Wiki:Entity-Component-System,ECS模型遵循Composition over inheritance的原则。这是守望先锋程序团队在GDC上的ECS架构与网络同步分享以及知乎关于OW的ECS架构以及ECS模型本身的讨论,关于游戏架构设计上使用ECS的好处以及ECS模型相对于传统OOP的优越性在上述文章中都可以找到,以下是个人的学习笔记。
- Entity : 无数据无逻辑,单纯是一个实例,拥有若干Component
- Component:只有数据没有逻辑,可以被Entity动态添加和移除
- System:只有逻辑,只关心Component不关心Entity
- World:缓存所有Entity与Component,并对System进行轮询,负责整个系统的运转
简单的例子:
Entity
// AddComponent的功能是在world中创建Component并且添加到该Entity的Component集合中。
public Entity bullet = new Entity(_entityID);
bullet.AddComponent<TransformComponent>();
bullet.AddComponent<MoveComponent>();
Component
class TransformComponent
{
Vector3 position;
Vector3 rotation;
}
class MoveComponent
{
Vector3 speed;
}
System
class MoveSystem
{
public void Update(float time)
{
foreach(var movecomponent in movecomponents)
{
// 查找该Entity是否拥有TransformComponent
var transformcomponent = movecomponent.sibling<TransformComponent>()
if(transformcomponent != null)
transformcomponent.position += movecomponent.speed * time;
}
}
}
ECS 模型的结构是非常简洁明晰的,而且由于Component 中只有状态没有逻辑,可以很大的提高 Component 的复用度,以及同类 Component 在内存中是连续分布的,可以很大的提高缓存命中率(关于这点还在想该如何设计数据结构才能达到目的)
对于System需要使用的(整个 world 中唯一的)状态,遵循 System 中无状态的原则,使用 SingletonComponent 的方式去实现(参考 OW ECS 架构中的 SingletonComponent 部分)
将共享的 System 函数分解成 Utility ,减少调用,整合调用点
延迟执行(Deferment)的使用,即先缓存需要执行的状态,在更好的时间点集中调用(这点有很广泛的应用价值)