我对ecs系统的一点看法

谈论什么

这里我主要从工程或设计的角度讨论, 至于ecs对性能的优化方面

的事情我这不做过多介绍.

  • 为什么要把ec系统里的c分为coponent与system两快

  • ecs系统的优点

  • ecs系统的缺点

  • 从编程演化看ecs系统

  • ecs总结

  • 吐槽一下unity 的ecs系统

为什么要把c与s分开

这是我在用ecs系统时最大的一个问题,现将我的一点想法与大家分享

原因在于将c与s分开之后,就可以降低逻辑之间的关系,极大的降低系统复杂度

原理如下:

当system(逻辑)需要其他数据,直接找到entity好了,数据都在上面。

没有必要与其他system(逻辑)有关联

所有的关联都在entity及其component上

在拓扑关系里,若将所有entity看成一个节点,那么所有system都依赖这个

节点,而且entity与compoent又不依赖system,这样一个星形的单方向的拓扑结构

极大的简化了系统的之间的关系与复杂度。

下面讲的优点都在这基础上具体的表现。

ecs系统的优点

  • 规则简单易于推广

只有component能存数据,只有system能有行为, entity结构永远不变

规则就这么简单,比较容易记住

  • 降低了复杂度

由于ecs系统的所有操作都是对entity内的数据(Component)的直接修改

因此大大的降低了不确定性与花费的 精力

举例: 系统庞大之后, 做一个系统或功能可能要依赖好几个系统

用面向对象或ec系统的时候,你可能需要调

用一些函数

而这些函数有可能代价很高很复杂, 比如内部调用的文件存储、

网络、渲染api这类复杂的操作,需要很小心的调用

不然很可能就会有性能问题。

而在ecs系统中即便是调用的辅助函数, 本质都是对数据的操作

能够很方容易估算出调用的代价,而且代价也相对较小。

  • 不需要缓存机制

正因为ecs创建entity代价小,

创建对象直接生产,不需要内存池对象池也相应减少了代码复杂性

  • 容易写出好的代码

由于ecs系统强制把数据和行为分开了, 写逻辑的程序就不容易出错了。

因为本质上写的东西就是对纯数据的操作。

规范更容易推进, system里面不保存任何数据, 规则也很清晰,容易执行

  • 统一数据的存放方式

需要记录的东西都使用component来记录

这样大家就不会出现数据存储在一些奇怪的地方

  • 统一了数据的获取方式

原有的方式,每个系统的调用, 需要用到的数据可能有各种获取方式

比如调用某个或多个方法来获取。

而ecs系统则统一使用类型的组合作为数据的获取条件

  • 二进制友好

游戏中常需要保存游戏进度, 或是同步数据给服务器。

ecs系统里只要把特定的component筛选出来序列化就可以, 非常方便

  • 降低了代码间的耦合

所有的system 可以做到只依赖 相应的component

直接的交互也使用component来进行, 这样就极大的降低了代码间的耦合

ecs系统缺点

  • 模块独立性不强与系统强关联

一些功能的重用必须要有整个ecs环境才能运作, 模块独立性不高

一些底层功能, 如网络,文件操作使用ecs就不好做封装

  • 模块间无法隐藏数据

正因为模块间无法隐藏数据, 导致一个问题就是设计不好的数据会影响所有系统

对写的不好的代码容忍度比较低

  • 无法统一编程模型, 只能解决特定问题

无法像ec系统, 比如com组件那样将所有的代码都用一套来封装

  • 新的思考模型

新的编程模型需要新的思考方式,大家需要习惯一下

  • 对异步处理支持不好

编程演化

  • 01编程

    • 有就行了, 要求不要那么高
  • 汇编

    • 人类容易记住字母的命令,而不是01的数字
  • c语言

    • 演化为数据结构与算法, 因为发现代码通常不会改变。

    这样把结构与算法分开更加容易写出健壮的代码,

    代价是不能在运行时通过动态修改代码获得最高的性能

  • oop 初代

    • 人类对事物的认知本来就是对对象进行分类来思考的

    oop能降低大家的思考难度,而且可以将垃圾代码隐藏起来

    代价是性能有所降低

  • oop ec编程

    • 在自然的环境下分类思考是可行的, 因为类都是不变的

    但在游戏里的类是会变的啊, 通过配置加个类型跟玩似的

    于是就强调面向行为

    具体做法是限制 类的继承,只使用组合。强调设计接口的不变。

  • oop ecs编程

    • 系统之间关系太复杂,性能要求也有所需要。

    通过限制编程的方式,逻辑上只对数据进行操作

    达到简化系统,降低大家对系统的理解成本,降低对逻辑编程的要求

基本编程方式的发展就是各种简化

  • 一种是将编程方式与人类思考方式靠近, 简化理解的成本,简化编程的难度.(设计一门新语言)

  • 一种是通过对已有编程方式的限制,简化系统的复杂度,出错的可能。(编码规范)

ecs系统总结

ecs的最大收益的,其实是做逻辑的程序,可以更加容易的写出优秀的代码。

ecs系统在我看来就是ec系统的一个子集,在ec系统上加上一些

限制条件容易做成一个ecs系统,ecs系统的好处是我们能够

更加容易的写出高质量的代码。

由于ecs的局限性, 主要用于上层架构, 不会用于底层架构

至于在ecs中需要调用到的外部api,通常都会在ecs中加个中间层并入已有的ecs系统中

比如要做网络同步, 就需要创间一个网络相关的system,再把数据同步出去

吐槽一下unity 的ecs系统

  • unity 的ecs系统更多是在性能上的优化方便上的便利,而不是保持ecs本身的简单化

  • unity ecs系统本身弄的复杂, 复杂在下面几个方面

    • unity 内部隐藏了太多细节

    • 隐藏了入口, 不方便从整体上来学习了解

    • 使用来太多attribute, 还有特定结构来实现基础功能

      比如system 之间的调用次序

  • 正由于unity ecs系统过于复杂, 导致无法直接将逻辑代码拷贝到服务器

你可能感兴趣的:(我对ecs系统的一点看法)