Unity下的ECS框架 Entitas简介
最近随着守望先锋制作组在gdc上发布的一个关于ecs的talk,ecs这个架构算是得到了一定的曝光度。
在这之前,github上就一直有一个C#的ecs框架名为Entitas,截止现在已经有1300+的star了,同时提供了和unity整合的方法(对,你可以不用unity,直接把它当C#的库来做其他的东西)
地址: https://github.com/sschmid/Entitas-CSharp
同时还有一个gitter:https://gitter.im/sschmid/Entitas-CSharp 很多entitas的开发者会在上面进行相关的问答,推荐时不时看两眼。
还有云风大大对守望先锋的talk的解析,http://blog.codingnow.com/2017/06/overwatch_ecs.html 推荐在用Entitas一段时间,熟悉ECS之后再看,写的非常棒。
要是对ecs有一定理解的人(一系列很不错的文章在 http://t-machine.org/index.php/2007/09/03/entity-systems-are-the-future-of-mmog-development-part-1/ ,主要是讲ecs相对oop的优点的,将OOP在MMORPG开发中的弊端批判了一番),可以知道ecs的优点之一在于缓存命中率极高。因为设计良好时,同一类component在内存中是连续排列的。但是出于种种原因,C#难以写出一个足够flexible的框架来实现这一优点。而Entitas使用了生成代码的方法,将这一优点保留了下来,同时也会生成非常友好的API以供调用。
目前Entitas的版本在0.42.3,算是还没有完全成型,但是满足我这种小打小闹写代码是完全可以的。
提到Entitas,就不得不说一下Unity中GameObject-Component的设计。有人认为Unity中这种架构也是ECS架构,但事实上
- Unity中的Component都是一个完整的类,缓存不友好。
- Unity中的Component包含逻辑。当然你也可以要求出程序员不能在Component里写Update等函数。
- Unity中你没办法去获取所有“有ComponentA和ComponentB的所有GameObject”,而在ECS中这是非常必要的。
总的来说,Unity中的架构,更多的是OOP中的“组合优于继承”这一思想的实践,而不是真正的ECS。
回到Entitas上来。Entitas初学者普遍存在的一个问题是Entitas如何和Untiy交互,因为它们的Entity和GameObject并不存在任何实质上的联系。(你把Entitas的代码拿到Unity外面,完全可以运行,如果你没有用Unity的API的话)
这里先推荐一篇他们自己的talk:https://www.youtube.com/watch?v=lNTaC-JWmdI ,如果能看懂的话那这个问题基本上就解决了。
这里再简单的说一下我的思路。一般来说,我倾向于理解Unity作为一个“展示”的工具。所有游戏的逻辑都在Entitas中运行。
如果我要一个Entitas中的Entity在Unity中显示的话,我会添加一个ViewComponent,包含一个GameObject字段,表示它在Untiy中对应的GameObject。
然后添加一个ViewPositionUpdateSystem,它对有ViewComponent和PositionComponent的Entity感兴趣,会在PositionComponent改变时,将ViewComponent中的View也改变位置,此时Unity中你看到的GameObject的位置也就跟着改变了。
这里题外话一点,在一般的ECS介绍文章中,会从类似“物理系统只关心有PhysicsComponent的Entity,渲染系统只关心有RenderComponent的Entity“类似的话开始。在这里,我们也做了类似的事情。只不过我们的“渲染系统”的渲染工作要简单得多,只需要把Unity里的GameObject的位置挪一挪就行了。
再说说物理系统。如果你心大的话,完全可以去找一个第三方库跟Entitas直接接轨,但是用Unity的物理系统也是可以的。关键点和上面一样,将Unity视作一个工具。
首先,既然你用Unity的物理系统,那你想要的Entity肯定得有个ViewCompoennt,然后他的GameObject上有你配置好的碰撞体等。接着你可以在它的GameObject上添加脚本,在OnTriggerEnter等物理相关的函数中通知Entitas发生了物理碰撞。你可以写一个CollisionComponent,其中保存碰撞的信息,在OnTriggerEnter中填写它添加到Entity上去;也可以不添加到Entity上,而是直接放在Contexts中等着感兴趣的人去处理它(你可以添加到一个全局Component的List里,也可以直接新建一个Entity放那儿,都行)。
这其中比较细节的地方是在OnTriggerEnter中填写碰撞信息。有人可能发现了,我们在Entitas的Entity中在ViewComponent里保存GameObject的索引,但是我们在OnTriggerEnter中,我们并不能反过来获得Entity的索引。其实道理是一样的,我们可以写一个MonoBehaviour,其中有一个Entity字段;在你将一个GameObject用ViewCompoent添加到Entity上时,同时给这个GameObject也添加这个Monobehaviour,写上Entity的索引就行了。
因为这个需求实在太常见了,Entitas里内置了一个方法,将Entity和GameObject链接起来。在命名空间Entitas.Unity中提供了GameObject的扩展方法Link,调用该方法的效果跟上一段所说相同,会添加一个叫EntityLink的MonoBehaviour,然后就可以通过这个MonoBehaviour获取到它链接的Entity了。
另外如果有任何问题的话欢迎回复或者私信讨论,本人对ECS也处于不断学习理解的状态,希望可以共同进步
Unity下的ECS框架 Entitas简介的更多相关文章
- Unity下的开发框架--适应web和微端游戏异步资源请求的框架
一. 内容简介: 1. 框架对Web与微端游戏特性的支持: Web和微端游戏最重要的特性是,资源是持续从服务器上即时下载下来的.而保证体验流畅的关键就是保证资源下载分散到持续的体验过程中,并保 ...
- 理解ECS的概念和Unity中的ECS设计
组合优于继承 ecs的概念很早就有了,最初的主要目的应该还是为了改善设计. e-c-s三者都有其意义,e-c是组合优于继承,主要用以改善oo的继承耦合过重以及多继承菱形问题. oop常见设计里,每个g ...
- 从零开始写一个武侠冒险游戏-0-开发框架Codea简介
从零开始写一个武侠冒险游戏-0-开发框架Codea简介 作者:FreeBlues 修订记录 2016.06.21 初稿完成. 2016.08.03 增加对 XCode 项目文件的说明. 概述 本游戏全 ...
- android hook 框架 libinject2 简介、编译、运行
Android so注入-libinject2 简介.编译.运行 Android so注入-libinject2 如何实现so注入 Android so注入-Libinject 如何实现so注入 A ...
- 出售一套Unity + Lua热更新框架代码
出售一套Unity + Lua的客户端框架代码,功能有资源管理.网络通信.配置文件解析.热更新.文件读写.Lua加密揭秘.UI框架.打包工具.编辑器工具等,已经在多个实际项目(已上线)中使用.代码优雅 ...
- 无废话Android之android下junit测试框架配置、保存文件到手机内存、android下文件访问的权限、保存文件到SD卡、获取SD卡大小、使用SharedPreferences进行数据存储、使用Pull解析器操作XML文件、android下操作sqlite数据库和事务(2)
1.android下junit测试框架配置 单元测试需要在手机中进行安装测试 (1).在清单文件中manifest节点下配置如下节点 <instrumentation android:name= ...
- Debian下安装Firefox与flash简介
Debian下安装Firefox与flash简介 由于Debian在Firefox的版权上出现了问题,导致官方发布的Debian系统不能使用默认的Firefox浏览器,最后官方重编的Firefox改名 ...
- Net Core下多种ORM框架特性及性能对比
在.NET Framework下有许多ORM框架,最著名的无外乎是Entity Framework,它拥有悠久的历史以及便捷的语法,在占有率上一路领先.但随着Dapper的出现,它的地位受到了威胁,本 ...
- windows环境下安装yaf框架
windows环境下安装yaf框架 在windows下安装yaf框架 准备工作: php环境(过程略,wamp,xampp,phpstudy都行,php版本大于5.3) git工具(需要从github ...
随机推荐
- LintCode-56.两数之和
两数之和 给一个整数数组,找到两个数使得他们的和等于一个给定的数 target. 你需要实现的函数twoSum需要返回这两个数的下标, 并且第一个下标小于第二个下标.注意这里下标的范围是 1 到 n, ...
- Unsupported major.minor version 52.
面试的时候,京东和美团,360的面试官都问到了同一个问题,java1.7与java1.8的区别, 于是想做个小小的例子: 我的eclipse刚开始是1.7的,后来,我把环境改成了1.8的, 方法:右击 ...
- ASP.NET MVC4中使用bootstrip模态框时弹不出的问题
最近发现使用在MVC中使用bootstrip的模态框时弹不出来,但单独建立一HTML文件时可以弹出,说明代码没有问题,经过多次测试发现,在MVC的cshtml文件中添加上以下语句就能正常 @{ Lay ...
- 实用图像处理入门 - 1 - opencv VS2012 环境搭建
标签中的部分 font-family: 华文细黑; font-size: 26px; font-weight: bold; color: #611427; margin-top:40px; } h2 ...
- BZOJ2151 种树(贪心+堆+链表/wqs二分+动态规划)
dp容易想到,但没法进一步优化了. 考虑贪心,每次选出价值最大的物品.但这显然是不对的因为会影响其他物品的选择. 于是考虑加上反悔操作.每次选出一个物品后,将其相邻两物品删除,再将原物品价值变为相邻两 ...
- [洛谷P1341]无序字母对
题目大意:给一张无向图,找一条字典序最小的欧拉路径 题解:若图不连通或有两个以上的奇数点,则没有欧拉路径,可以$dfs$,在回溯时把这个节点加入答案 卡点:没有在回溯时加入答案,导致出现了欧拉路径没走 ...
- bzoj 1037: [ZJOI2008]生日聚会Party (dp)
dp,但是要顺推容易点 const mm=; var f:..,..,..,..]of longint; n,m,kk,now,sum,i,j,k1,k2:longint; function max( ...
- BZOJ2286:[SDOI2011]消耗战——题解
+++++++++++++++++++++++++++++++++++++++++++ +本文作者:luyouqi233. + +欢迎访问我的博客:http://www.cnblogs.com/luy ...
- BZOJ1458 士兵占领 【带上下界网络流】
题目链接 BZOJ1458 题解 对行列分别建边,拆点,设置流量下限 然后\(S\)向行连边\(inf\),列向\(T\)连边\(inf\),行列之间如果没有障碍,就连边\(1\) 然后跑最小可行流即 ...
- BZOJ2186 [Sdoi2008]沙拉公主的困惑 【数论,欧拉函数,线性筛,乘法逆元】
2186: [Sdoi2008]沙拉公主的困惑 Time Limit: 10 Sec Memory Limit: 259 MB Submit: 5003 Solved: 1725 [Submit] ...