ECS系列一:简介

关注点比较独特 :joy:

对我来说我是比较喜欢ecs的数据分离的能力。做过几个rpg的项目,对一堆装备角色属性混杂在那么几个文件里面很是抵触。直到了解了ecs才知道自己要追求的代码框架发展方向。

1赞

ecs的开发,本身就是反oop的
所有的实体上,都是挂着一堆组件
开发各个system,就是面向数据的开发

数据拆分,确实比较反人类,但是,我们确实没必要把数据放一起,各司其职就好了。
如果需要对数据进行统计分析,上报另外的系统就好了,这不是ecs所做的事

一个实体身上挂了太多组件后会带来很大的心智负担。比如你根本不知道这个实体身上挂了多少组件,也会不好理解原作者为什么会这样组合这些组件,也可能自己都不理解自己当初怎么这样的组合这些组件。这块不知道有何高见。

实体上挂组件,本身就是面向对象的思维,为什么实体上要挂组件呢?
实体只是一个id而已,实体自身有什么作用呢?
没有啊,数据在组件上,逻辑在system上。
理论上,我们只需要有组件,操作的是实体id为XX的组件上的数据而已。
system只关心组件上的数据,根本不关心实体是谁,只要有血条,我就搞。
我不关心血条是玩家的,还是npc的,是人物头上显示的,还是UI面板显示的。
这些不是它关心的东西。
同样,我们也并不关心实体上有哪些组件,因为你不是面向实体,或者说,面向对象编程。

1赞

不同职责的组件之间交互如何处理呢

不同组件为什么需要交互?
组件只是数据,
我没看到需求,你可以举个栗子。

站在系统的角度逻辑都是面向组件的。但是凡是流程都有个开头,必须先创建实体才能有组件。挂载组件也是挂载到指定实体上。那么还是会出现我上面说的问题。

按我自己的处理,交互写在System里面,或者单独封装个功能函数处理交互。

创建实体,本质上就是创建一个唯一id
假设组件不能脱离于实体,哪怕全局组件,也是位于一个全局实体上。
那么,创建组件的时候,必须指明实体,也就是那个id,
如果简单粗暴一点,直接丢到一个kv结构里,例如map里,key就是实体id。
实体自身,没有逻辑,因为逻辑在system里,它也没有数据,因为数据在组件里。
而对象是由它自身的数据以及维护这些数据的方法所构成。那么,实体就不是对象,没有作为对象存在的意义。

你的意思是实体身上有多少个组件并没有关系,反正实体不会去操作这些组件,组件都是分派到各个系统去处理逻辑。

对啊,实体根本不关心自己身上有什么组件,它什么都不关心

我又回来了。

1、OOP编程并不是你必须得将所有数据都堆在一个类中,而是利用好ts的interface,和继承。
2、OOP败也继承,因为大部分继承其实只需要基类的一部分数据或接口,大部分是不需要的,不需要的这些就成了负担。
3、但并不是说OOP不好,对人友好这块就完胜了。

4、ECS对人不好友,但在Unity,利用数据逻辑拆分,就可以对数据进行任意内存上的布局上的控制达到提高CPU访问数据速度的目的;
也因为只剩下纯数据,那就可以让多线程访问存在可能,所以并发优势极大,特别是对于只读数据。
这两个优点,让人在某些场景下可以容忍他的缺点了。
5、ts/js版本的ecs就是放弃了这两个最大的优点,剩下的就是“数据驱动”和“逻辑数据拆分”的不那么明显的优点了。
而“逻辑数据拆分”是不是优点呢?某些情况下是的。
值得放弃OOP的优点么?那得看个人选择了。

当然,这个世界并不是说只能选一个。
全都要(混合使用)也是可以的。

或许以后webassembly有转机。

1赞

赞同,小孩子才做选择题,大人就该全都要。腿好看的抱来看腿,脸好看的抱来看脸,活好的…超纲了

说白了,ECS,Node-Component,MVC,都是模式而已,脱离具体问题谈设计、脱离具体开发人员谈应用,都是扯蛋。

开发的游戏和开发的团队,决定了技术选型。

如果使用不了多线程和内存块优化,return ecs.allOf(NodeComponent, TransformComponent);这个地方就会耗费很多性能,特别是数据量非常大的时候,还有数据随机在更新的时候。反而会比普通模式性能还差。
ECS的优点是,内存块存储,能快速copy和移动,以及查询。二是多线程,这个最重要,因为是基于数据的,对数据的查询工作非常多,没有多线程相当于白干。

最耗性能的地方确实是在判断实体是否符合筛选规则的地方。就像你知道在Creator里面不停addChild然后destroy结点也很耗性能,然后你会用缓存或者其他方式避免这些操作一样,你也可以不去不停的给实体添加和删除组件,从而导致不停去判断实体是否符合筛选规则。

github 的仓库不再维护了么,我看了下最新的 commit 都是 15 个月前了

没有什么新的想法,加上没有在做CocosCreator的项目,所以没什么改动。后面会去看看其他ecs的库,学习学习。
如果你有想法也可以在github上提出来。

带佬看看私信