https://www.cnblogs.com/yangrouchuan/p/7436533.html

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架构,但事实上

  1. Unity中的Component都是一个完整的类,缓存不友好。
  2. Unity中的Component包含逻辑。当然你也可以要求出程序员不能在Component里写Update等函数。
  3. 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也处于不断学习理解的状态,希望可以共同进步

ECS简介的更多相关文章

  1. Unity Jobsystem 详解实体组件系统ECS

    原文摘选自Unity Jobsystem 详解实体组件系统ECS 简介 随着ECS的加入,Unity基本上改变了软件开发方面的大部分方法.ECS的加入预示着OOP方法的结束.随着实体组件系统ECS的到 ...

  2. 组件-实体-系统 Entiy-Compoent-System ECS架构整理

    继承体系的问题,为什么要用ECS 面向对象的问题 当一个新的类型需要多个老类型的不同功能的时候,不能很好的继承出来 游戏开发后期会有非常多的类,很难维护 游戏中子系统很多,它们对一个对象的关注点往往互 ...

  3. Unite Beijing 2018 参会简要分享

    一. Training Day 主讲人:鲍建运 操作:马瑞 课程包括较为完整的功能,如灯光设置,角色动画控制,Cinemachine,Timeline,AI寻路,以及最新的Post Processin ...

  4. Entitas实现简析

    Entitas实现简析   这里主要讲Entitas的执行原理,不讲Entitas的代码生成方面. ECS简介   ECS(实体-组件-系统)是一种常用于游戏开发的架构模式.   实体: 实体只是一个 ...

  5. 阿里云ECS(云服务器)之产品简介

    参考阿里产品文档:https://docs.aliyun.com/?spm=5176.100054.3.1.ywnrMX#/pub/ecs/product-introduction/concept

  6. Unity下的ECS框架 Entitas简介

    最近随着守望先锋制作组在gdc上发布的一个关于ecs的talk,ecs这个架构算是得到了一定的曝光度. 在这之前,github上就一直有一个C#的ecs框架名为Entitas,截止现在已经有1300+ ...

  7. 怎么样cocos2d-x正在使用ECS(实体-包裹-制)建筑方法来开发一款游戏?

    简介 在我的博客,我翻译的几篇文章ECS文章.这些文章都是从Game Development站点.假设你对这个架构方式还不是非常了解的话.欢迎阅读理解 组件-实体-系统和实现 组件-实体-系统. 我发 ...

  8. 云服务器ECS优惠券 阿里云 ecs 5折优惠码 阿里云5折优惠码 阿里云5折推荐码 阿里云优惠码 阿里云的5折优惠券 阿里云服务器购买优惠码 服务器购买优惠码

    阿里云代金券 | 阿里云优惠券云服务器ECS,就是阿里云服务器,大家一定要清楚.云服务器ECS优惠券官方领取优惠页面:https://promotion.aliyun.com/ntms/act/amb ...

  9. ECS上nginx搭建反向代理通过内网访问阿里云OSS服务

    对于付不起钱的小伙计,为了给公司省钱,想尽一切招数.今天就来分享一个使用阿里云OSS存储搭配CDN使用的网站服务器部署方法. 简介 阿里云OSS 阿里云提供的一种文件存储方案,和我们以前接触的百度云B ...

随机推荐

  1. CentOS 7.2 PowerShell下安装Azure Module

    目前Linux版本的PowerShell还是Alpha版本,所以很多功能不能使用. 比如通过Powershell命令:install-module AzureRM在线安装Azure的Module.但我 ...

  2. hihoCoder1296:约瑟夫问题

    时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi和小Ho的班级正在进行班长的选举,他们决定通过一种特殊的方式来选择班长. 首先N个候选人围成一个圈,依次编号为0.. ...

  3. [转] LINUX 三种网络连接模式

     Linux下NAT模式和桥接模式的网络配置 最近在配置linux虚拟机的时候发现有很多坑,现在记录下来以防日后又跳到坑里. 我的运行环境是:主机 windows 7  虚拟机 Virtualbox ...

  4. SQL 2008提供几种数据同步方式

    SQL 2008提供几种数据同步的方式如下. 1.日志传送(Log Shipping),定时将主数据库的日志备份,恢复到目标数据库. 2.数据库镜像(Database Mirror),原理同日志传送, ...

  5. 2015.4.25利用UIAutomation 替代API函数,解决了ListView无法读数据的难题,顺便实现了鼠标模拟滚轮

    UIAutomation比API的优点是类似于消息处理机制,而不是主要靠模拟鼠标键盘发送消息 首先添加引用UIAutomationClient和UIAutomationTypes,在安装.net3.5 ...

  6. Hibernate面试总结

    SSH原理总结 Hibernate工作原理及为什么要用: 原理: hibernate,通过对jdbc进行封装,对 java类和 关系数据库进行mapping,实现了对关系数据库的面向对象方式的操作,改 ...

  7. NodeJS之Url的使用

    一.通过http模块中的request事件可以得到在服务端拿到客户端的有关url的数据(req.url),其中req.url得到的数据是端口号后的所有路径,之后通过调入url模块对获取到的req.ur ...

  8. SQLServer SDK

    https://www.cnblogs.com/Leo_wl/p/3451865.html 回到目录 SQLSERVER一些公用DLL的作用解释 如果你的SQLSERVER安装在C盘的话,下面的路径就 ...

  9. linux 信号量之SIGNAL 0<转>

    我们可以使用kill -l查看所有的信号量解释,但是没有看到SIGNAL 0的解释. [root@testdb~]# kill -l 1) SIGHUP 2) SIGINT 3) SIGQUIT 4) ...

  10. loop

    -- ------------------------loop---------------------------delimiter $DROP PROCEDURE IF EXISTS my_cou ...