近期在游戏demo中试验ECS, 深入研究Unity官方的ECS框架和第三方Entitas框架, 分享下使用ECS的心得。
Unity在2018版中加入了ECS系统, 但处于小白鼠阶段。默认不是Unity的一部分, 需要手动下载代码并导入Packages(新特性)。官方提供海豚例子, 但除此之外例子和资料非常少。所以完全无法,也不敢在demo中贸然引入这种系统,所以放弃官方ECS系统。
第三方的Entitas( https:// github.com/sschmid/Enti tas-CSharp )ECS框架从2015年就开始在各地演讲中介绍。整体框架基于代码生成, 能解决一部分的代码爆炸问题, 而且性能也要好一些。例子,介绍非常丰富,例子虽然基于不同版本的Entitas,特性支持和最新版差不太多, 只是写法有细微差异, 对于理解来说无碍。
经过1~2天的改造, 终于将demo从传统Unity写法改造为ECS标准写法,新增了46个文件, 而传统逻辑一共只有16个文件,大概对比下ECS的特点和差异。
Entitas的ECS系统
1. 本来在一个对象中添加一个类字段的过程,ECS需要添加一个类代表Component,并且代码生成。
这个字段一般用于描述对象的资源,处理显示的GameObject, 表示对象的类型等。
2. 本来一个对象的业务逻辑处理过程直接用方法解决的, ECS需要新加一个System,而操作对象需要使用Filter或Group查询获得。
3. 一系列的操作, 需要拆分为多个System和Component拆分处理。如果System顺序不对, 会造成一些诡异的bug。
4. Component不仅仅是Model承载体, 也可以是参数的数据结构。参数Component通过Entity传递到System处理。 例如: 通过ECS创建一个方块的过程,使用CreateTileComponent,包含创建Tile的位置, 创建Entity并添加CreateTileComponent, 在CreateTileSystem中处理就创建了Tile,处理完成时, 需要将传入的Entity.Destroy掉。
6. Entity上修改Component的过程, 会触发事件。修改的过程需要使用RelaceXXX,XXX表示组件名。组件可以频繁修改, 不用担心添加和删除组件过程的性能, Entitas底层处理性能只相当于指针赋值的性能。
ECS像什么?
1. ECS中的System类似触发器系统(Event-Condition-Action),其中,Event对应Entitas的GetTrigger+Collector,表示触发事件。Condition对应Filter表示在事件来源对象中找到需要的对象。 Action对应Execute,表示实际的操作。
2. ECS中的Component类似不用 lua 扩展的 Redis 或者不用存储过程的MySQL, 纯粹纯数据, 而不能对数据有任何封装操作。没有lua和存储过程支持的db写起来还是比较费劲的,但ECS就是那么的纯。
3. ECS中的Entity很尴尬,因为Component是按类别连续存储的以保证性能。 逻辑又需要Entity组合成逻辑需要的复合对象。 两边都要照顾,所以这种设计就让代码量巨增,可读性下降。
ECS企图用一套框架灭掉设计模式
1. 单件(Singleton)在Entitas用Unique标签标记Component, 在Context中就是唯一的, 其实也就是Singleton。
2. ECS干掉了传统的工厂模式,底层统一对对象(Entity)和属性(Component)统一管理。需要按Component中的值找回Entity时, 可以使用EntityIndex。
3. Entity携带不同的组件时,整个创建和销毁过程被记录并恢复,其实就是Command模式
ECS适合做UI框架(类似MVVM,MVC,MVP)么?
ECS不是专用的UI框架,但是可以对不同系统和数据间解耦。传统代码中数据修改后的Callback,ECS也可以用Listener做, 但Listener因为能保存数据, 就需要用Component保存。 所以你需要面对的是,一个Button,响应创建一个参数用的Component和System,还要为数据改变写一套ListenComponent和Listener处理的System,酸爽吧?
Minecraft适合ECS来做么?
可以,性能应该能提升不少,但是代码会更繁琐,特别像 Java 这种啰嗦语言配上ECS这种啰嗦框架,估计代码量翻翻还是很轻松的。MC属于特殊类型的游戏,适合特殊领域特别优化,也就是专门为方块做出特别的设计来做优化。ECS属于通用框架,即便性能OK,但是代码未必能有良好的可读性。
体量小的游戏适合用ECS来做么?
可以,但不建议。特别是只有几个人维护的工程,贸然上ECS系统,会让系统变的极为复杂。当然你会说,如果开发到后期,传统开发模式会导致代码会乱,ECS会好些吧。掌握ECS也不是一天两天的事情,不熟悉ECS的 程序员 设计出来的系统获得的优势可能还不如用传统设计方法好呢。
架构解决的是人的问题, 人都有问题,用什么框架都没办法。
到底什么项目适合用ECS?
1. 大量的小个体不断的生成和销毁以及显示,例如: 攻城战中,要体现每个角色的移动,战斗。
2. 多于5个人编写核心战斗逻辑。互相协作和模块切分,需要一个大家都能信服的框架,ECS可以选择。
P.S.
不要造ECS的轮子!
很多同学看了ECS基本原理,在没有深入使用过任何ECS系统时马上操刀造轮子。ECS系统确实看起来简单。实际造下来你会发现,性能非常糟糕以及不知道一些逻辑如何用ECS来解决。
总结:
1. ECS确实为性能而生,没有并发加持性能的ECS都是耍流氓,要快就要快到极致。
2. Unity中,ECS并发能扩展CPU的利用率,但是GPU的性能依然还是DrawCall优化那一套,别期望ECS会颠覆Unity,性能也不会快到飞起,关键还是要看具体的项目和人。
3. ECS是万能框架,但不全能。传统架构和设计思想也不是一无是处,熟啥用啥,怎么快怎么来!
无耻的广告链接,请各位支持
以上所述就是小编给大家介绍的《Entity-Component-System框架心得》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
The Pragmatic Programmer
Andrew Hunt、David Thomas / Addison-Wesley Professional / 1999-10-30 / USD 49.99
本书直击编程陈地,穿过了软件开发中日益增长的规范和技术藩篱,对核心过程进行了审视――即根据需求,创建用户乐于接受的、可工作和易维护的代码。本书包含的内容从个人责任到职业发展,直至保持代码灵活和易于改编重用的架构技术。从本书中将学到防止软件变质、消除复制知识的陷阱、编写灵活、动态和易适应的代码、避免出现相同的设计、用契约、断言和异常对代码进行防护等内容。一起来看看 《The Pragmatic Programmer》 这本书的介绍吧!