库
- Entitas-CSharp(class based, oop)
- ecslite(struct based, sparse set)
库的对比
https://github.com/Chillu1/CSharpECSComparison
库的性能测试
https://github.com/Doraku/Ecs.CSharp.Benchmark
库的选择
选用ecslite
- 代码简洁,易于修改、扩展
- 没有代码生成,干净
问题点
- 如果使用request/event(添加component)来处理system间的“通信”,怎么决定request/event是存活一帧、两帧?还是延迟一帧再调用?还是某个system里自行消耗(移除component)?也可以是component包含一个queue容器,每帧依次消耗?
2. 如何从oop向dop转变?如何设计dop模型? - ecs如何模块化?并尽量保证不受执行顺序影响?如何编写模块测试?
- 如何从gameobject获取到entity对象?安全?方便?性能?
- 能否和现有oop代码结合?例如封装到c或者s里去?
- system无状态,那么状态可以保存到哪里?
- 单例组件?
- 如何减少大量相同代码?如何复用?system能不能使用继承?有何优劣?
- 出现bug,如何调试?从哪些方面入手?
- 如何让一些system在entity变化时,抛出事件,减少system的遍历?需不需要?
- 如何使用jobsystem?
- 如何处理包含关系?见Q.1
- 如何描述层级结构?例如场景节点树
- 不同ecs框架,如何安全创建/销毁ent?
- ecs是否需要代码生成?
- 如何使用ecs制作网络游戏?客户端预测?客户端回滚?回放?
使用ecs
组织模块
例如 CameraFeature 包含 CameraZoomSystem 和 CameraMoveSystem
组件特性
IEcsAutoReset,自动重置,用于清理资源,处理引用类型
ReactiveSystem
开启 LEOECS_FILTER_EVENTS 宏,init里使用接口添加自己的监听实现类(待验证)
。这样可以不用实现run接口,避免大量forloop。
使用array+interface实现的监听,非委托的方式,gc更少,但没有多线程支持
ecs的评估
ecs的优势
- 比ec更进一步,更细分,扁平化,也更抽象
- 逻辑数据完全分离
- 利于内存排布、多线程,提高性能(打个问号)
ecs的劣势
- 过于规范化?
- 难抽象
- class数量变多(打个问号)
- system严格的执行顺序
- system之间的通信问题(打个问号)
Q & A
Q.1. ECS模型按列解耦功能确实挺好的,但是对于树形结构的数据,比如一场战斗有两个玩家,每个玩家有三个英雄,每个英雄有四个技能,每个技能有五段攻击。该如何设计才能更合理呢?
A. 这种叫做 Component 的引用,在我的库中有专门额外结构解决这类问题。在上文中已经提到过了。
那么,“比如一场战斗有两个玩家”,就可以把“战斗”看成是一个独立的 Component ,玩家则引用它。“战斗”这个 Component 并没有归属到两个玩家中的特定一个。
我们可以
- 用一个 system 遍历玩家,把战斗需要的信息复制到关联的“战斗”中。
- 用一个 system 遍历战斗,结算战斗结果。
- 用一个 system 遍历玩家,取出战斗结果。
以上 1 和 3 均可以用 tag 标记出涉及战斗的玩家,过滤掉未参加任何战斗的玩家。
Q.2. 如何序列化/反序列化Entity?
A. 配置表加载,代码生成;使用unity的序列化制作蓝图,IConvertToEntity;
Q.3. Is it safe to store a List
A. https://github.com/sschmid/Entitas-CSharp/issues/964
关于接入已有工作流
- GameMode使用oop(可以是一个system基类?)
- 定义各种GameMode所有资源路径,excel/scriptableobj都可以
- 使用GameContext类定义GameMode上下文数据,这一块,可以自由发挥,用oop/ec都无所谓
- 数据集中化,可以使用asset接口异步预加载/下载资源,并且可以方便做池化,也可以延迟到使用时再加载
- GameMode里注册各种system,inject数据,启动ecs world
demo
ecslite都是简单的demo,可以去参考entities-csharp,有网络同步相关的demo
https://habr.com/ru/post/661085/
https://github.com/sschmid/Entitas-CSharp/wiki/Tutorials
references
https://blog.codingnow.com/2021/07/lua_ecs.html
// TODO 守望先锋ppt
AbilitySystem
TODO 究竟是oop的技能系统兼容ecs,还是纯ecs的技能系统?