ECS,全称是Entity Component System,即实体、组件和系统。据wiki,这三种概念的定义如下:
实体,一般用途的对象,可以用唯一ID来标识。
组件,是一组数据,可以是实体的一部分,也可以是实体和世界交互的中间数据(注意:没有功能)。实体由若干组件组成的,否则它就是一个空盒子。
系统,基于实体中的特定组件来实现特定功能,但是系统是集中批量处理所有的实体的。
这样描述还是很容易混淆,比如UE4里面也有Actor和Component,和ECS有什么区别呢?在UE4中,Actor也是由Component组成的,不过Component提供的是数据和功能的集合,所以在UE4中经常看到各种Component的继承。
而ECS架构中,组件除了没有功能之外,相同类型的组件还是集中存储的(同一个chunk内)。System每次运行时遍历所有具有指定组件的实体,集中处理这些组件。
unity ECS内存布局
ECS的这种数据组织方式类似列数据库,System类似无状态服务。
ECS的优势和劣势
相比OOP方式实现的Component,ECS中相同组件的数据是连续的,System又集中处理这些组件,可以方便的利用CPU Cache,提升效率。
由于System处理的可能是几个组件,ECS将组件尽量的最小化(否则会有很多数据冗余),这样就实现了数据的扁平化。同时,System间禁止相互调用,最大程度的实现了解耦。而OOP最被诟病的调用层次深,结构复杂等问题都被解决了。
ECS也有它的不足,众多的component和system会带来认知负担,而且system之间可能存在优先次序,排定这些次序需要技巧。
System之间禁止调用,对象间的交互需要用到延迟处理的技巧。比如A攻击了B,你只能先把A攻击和相关数据记录下来,等专门处理受击的系统处理到B的时候再计算对B造成的伤害。那如果B对A有反弹伤害呢?还得再来一遍。
ECS的应用范围
ECS在处理扁平化数据和逻辑有很大的优势,比如移动、碰撞、渲染等,数据单纯且集中,处理起来效率高。而对于技能、AI逻辑来说,需要用到的数据较多,交互对象也多,并不能充分利用cache优化,而技能的思考流程也是反直觉的。