先介绍下优点:
Entity-Component-System的优点
- 高性能
- 易编写出高度优化的代码
- 易编写出可重用的代码
- 数据在内存中是紧密排列的
- 和Job System、Burst一起可以获得更高的性能
举个栗子:
- 子弹反应系统—>技能系统—>运动反应系统顺序,会导致技能系统创建了子弹,子弹添加了运动组件,运动反应系统,提前计算(此时子弹的方向还未计算),下一帧才会计算子弹的反应系统;导致方向不对
-
- 解决方案:
调整系统顺序,(简单但是会增加开发成本,思维混乱)
规范
-
- 凡是组件的反应系统,对顺序是有要求的,不要再反应系统中计算组件中的数据
- 直接在创建实体时,这些组件的数据就必须计算完毕
- 所有逻辑都有ECS ,修改场景中的数据,没有反应;场景只是用来播放数据的表现的;
-
- ECS逻辑帧与渲染帧并没有对齐,差距很大;场景必须使用插值来流畅画面;
- 修改ECS中的数据后,场景会插值进行更新,不是立刻更新的,所以想要立刻更新到显示层,需要调用UnityServerice.RefreshEntity(Entity)
- 尽量不让组件之间产生初始化的依赖关系;少用反应系统初始化组件,
-
- 即使要初始化组件,组件也不依赖其他组件,
- (其他组件可能也要在反应中初始化;顺序无法保证)
- Add组件时,默认会重用之前的组件,导致旧组件的数据不会初始化;造成逻辑错误;
-
- 使用Add(false)的方式,添加组件,这个方法会重新new一个组件对象
- 性能好的方式如果需要使用最新的组件,那让组件实现IResable接口,然后使用ReplaceNew的方式添加组件,这回使之前的组件调用这个接口后在使用。
- 数据的计算时机
/:如创建子弹的命令,需要提供子弹的出生位置和选装方向;这个数据的计算不能放到实例化命令时计算,因为这时还未生成子弹,现在定死位置肯定有误;
所以应该把数据放到生成子弹时在计算;
PS:刚接触这个的时候感觉写法很不舒服,接触过一些项目之后才发现..真...真...反正我觉得我逻辑更顺畅了