组件-实体-系统 Entiy-Compoent-System ECS架构整理
继承体系的问题,为什么要用ECS
面向对象的问题
- 当一个新的类型需要多个老类型的不同功能的时候,不能很好的继承出来
- 游戏开发后期会有非常多的类,很难维护
- 游戏中子系统很多,它们对一个对象的关注点往往互不相关,比如渲染.网络,战斗数据,如果都对应一个基础角色对象,这个类就会很大
ECS,通过组合而不是继承的方法来进行实体的构建
- ECS的设计目的是用来把大量的模块进行集成并解耦,用最小的耦合来集成大量分散的系统
- 每个System可以只关注实体有什么,而不是实体是什么,这是与OOP的最大区别
- 在网络同步的预测错误后可以很方便的纠正(所有元素都用Component分离了)
- ECS的一个重要特性就是并发优势,因为提供了数据隔离
Unity推荐ESC的原因
- ECS专注于您正在解决的实际问题,即构成游戏的数据和行为。
- 为了配合使用Job System和Burst 编译器。
- 从以对象为导向的设计转到以数据为导向的设计,代码更为容易,也更易于他人掌握。
示例
假设一个简单的游戏,有石头,树,敌人,玩家三种物体
这个时候需要一个新的类型,可以攻击的树
- 按照OOP的设计大致是这样的
- ECS的设计大致是这样的
EvilTree拥有: Position,AI,Sprite,AABB
ECS结构图示
ECS基础规则
* Entity轻量级,甚至只有一个Id;
* System没有状态, Component 不带行为
* System不能调用其他System的函数,共享代码要放到Utils里(如敌对关系),Utils函数无副作用;
* 组件里复杂的副作用要通过队列的方式推迟处理,尤其是单例组件;
实体
一个实体指的是存在于你的游戏世界中的物体。实体在代码上就是一个组件的列表。
由于实体的结构实在是太简单了,所以很多实现都没有专门的设计一个实体的数据结构。相反的,一个实体就是一个ID,所有组成这个实体的组件将会被这个ID给标记,从而明确的知道哪些组件是属于哪个实体的。如果你想的话,你可以在运行时,动态的将组件从实体中移除或者增加一个或多个你感兴趣的组件。比如说,如果玩家发出了一个冰系魔法,将敌人冻住,你只要简单的将它的速度组件移除,那么敌人就静止住了。
组件
没有行为(改变数据),只是用来存储一些数据(全部公开), 每一个组件都描述了实体的某个属性特征。
每个System会以自己的角度对待组件,不同的观察者区别对待主体
单例组件: 属于单一匿名实体,可以直接访问,存放System大部分状态.比如Ipnut单例,从InputSys中剥离的数据.
系统
真正处理游戏逻辑的地方.
System不关注实体到底是什么,只关心组件集合,在这个集合上执行一组行为
只会有很少的System改变组件状态,自己管理复杂性
系统会指明所需要的组件集合,由主逻辑筛选出所有满足要求的实体
守望先锋的ECS
* Entity轻量级,甚至只有一个Id;
* System没有状态, Component 不带行为
* System不能调用其他System的函数,共享代码要放到Utils里(如敌对关系),Utils函数无副作用;
* 组件里复杂的副作用要通过队列的方式推迟处理,尤其是单例组件;
一个实体指的是存在于你的游戏世界中的物体。实体在代码上就是一个组件的列表。
由于实体的结构实在是太简单了,所以很多实现都没有专门的设计一个实体的数据结构。相反的,一个实体就是一个ID,所有组成这个实体的组件将会被这个ID给标记,从而明确的知道哪些组件是属于哪个实体的。如果你想的话,你可以在运行时,动态的将组件从实体中移除或者增加一个或多个你感兴趣的组件。比如说,如果玩家发出了一个冰系魔法,将敌人冻住,你只要简单的将它的速度组件移除,那么敌人就静止住了。
没有行为(改变数据),只是用来存储一些数据(全部公开), 每一个组件都描述了实体的某个属性特征。
每个System会以自己的角度对待组件,不同的观察者区别对待主体
单例组件: 属于单一匿名实体,可以直接访问,存放System大部分状态.比如Ipnut单例,从InputSys中剥离的数据.
真正处理游戏逻辑的地方.
System不关注实体到底是什么,只关心组件集合,在这个集合上执行一组行为
只会有很少的System改变组件状态,自己管理复杂性
系统会指明所需要的组件集合,由主逻辑筛选出所有满足要求的实体
EntityAdmin是个World,存储了一个所有System的集合,和一个所有实体的哈希表(ID为unit32)。
单例组件
示例:命中处理System
- ModifyHealthQueue组件,记录实体身上所有伤害和治疗效果
- MovementState组件,移动数据处理
- 一组Utility函数处理错误纠错,回滚相关Component
几个建议
- System定义组件的组合时,可以把组件标记为只读
- 实体生命周期建议立即创建,延时销毁
- 某些遗留子系统不能接入ECS时,就不要强行接入,保持子系统的整洁
- 事实证明,网络同步真的很复杂,所以必须尽可能的与引擎其余部分解耦,ECS是解决这个问题的好办法。
Unity中的ECS
在PackageManager中下载Entities
参考
- 暴雪<守望先锋>ECS简介
- UnityGithub上的ECS架构
- 知乎 一个ECS实现
- 云风 浅谈《守望先锋》中的 ECS 构架
- Entity Systems are the future of MMOG development 2007
- 理解 组件-实体-系统 (ECS \CES)游戏编程模型
组件-实体-系统 Entiy-Compoent-System ECS架构整理的更多相关文章
- Unityclient框架笔记二(组件实体开发模式的思考)
Unity的Entity-Component-System实现的很美丽,很灵活.许多文章也对这样的组件实体的开发模式倍加推崇.由于它契合这么一条规则:优先使用组合而不是继承. 可是实际开发过程中,限制 ...
- 设计系统(Design System),设计和开发之间的“DevOps”
最近,我们网站的上新增了几个新功能,比如通过导航栏的QR Code可以下载App:通过Carousel的方式,显示多条信息. 以往这样的功能可能需要2-3个Sprints完成,但是现在这些功能都是在一 ...
- 02Microsoft SQL Server 安装,卸载,系统服务,系统组件及系统数据库
Microsoft SQL Server 安装,卸载,系统服务,系统组件及系统数据库 1. Microsoft SQL Server 安装 通过单击下拉框,选择浏览,然后在Active Directo ...
- (转)内置系统账户:Local system/Network service/Local Service 区别
最近会转载一些 MSSQL 基础相关的文章. 参考文献: http://www.cnblogs.com/xianspace/archive/2009/04/05/1429835.html 前言 今天在 ...
- 疯狂java笔记(五) - 系统交互、System、Runtime、Date类
一.程序与用户交互(Java的入口方法-main方法): 运行Java程序时,都必须提供一个main方法入口:public static void main(String[] args){} publ ...
- php 分词 —— PHPAnalysis无组件分词系统
分词,顾名思义就是把词语分开,从哪里分开?当然是一大堆词语里了,一大堆词语是什么?是废话或者名言.这在数据库搜索时非常有用. 官方网站 http://www.phpbone.com/phpanalys ...
- Java开源生鲜电商平台-财务系统模块的设计与架构(源码可下载)
Java开源生鲜电商平台-财务系统模块的设计与架构(源码可下载) 前言:任何一个平台也好,系统也好,挣钱养活团队这个是无可厚非的,那么对于一个生鲜B2B平台盈利模式( 查看:http://www.cn ...
- [转帖]内置系统账户:Local system/Network service/Local Service 区别
内置系统账户:Local system/Network service/Local Service 区别 学习使用 xp_cmdshell 的时候 发现必须 sqlserver 的服务运行在local ...
- 系统内部集成测试(System Integration Testing) SIT 用户验收测试(User Acceptance Testing)
系统内部集成测试(System Integration Testing) SIT 用户验收测试(User Acceptance Testing) UAT SIT在前,UAT在后,UAT测完才可以上线
随机推荐
- uva 662
dp +路径输出 #include <cstdio> #include <cstdlib> #include <cmath> #include <stack& ...
- hdu 3943
数位dp #include <cstdio> #include <cstdlib> #include <cmath> #include <stack> ...
- java截屏简单例子
原文:http://www.open-open.com/code/view/1444211411979 java截屏 * 运行后将当前屏幕截取,并最大化显示. * 拖拽鼠标,选择自己需要的部分. * ...
- eclipse中maven插件上传项目jar包到私服
我们知道,每一个公司都会有自己的工具包或公共包.这样的包就能够上传到公司的maven私服,就不用每一个人都去同步开发包了. 那么,怎么把本地项目打包并公布到私服呢?依照例如以下步骤就能够轻松完毕. 1 ...
- Oracle 数据库管理员的任务
设计.实施和维护 Oracle 数据库时,按优先次序排列的任务包括: 1. 确定数据库服务器硬件 2. 安装 Oracle 软件 3. 为数据库和安全策略制定计划 4. 创建.移植和打 ...
- ln 软连接 & 硬连接
创建软连接的方式 #ln -s soure /file object 创建软连接是连接文件本身,可以跨分区建立软连接,不会应为不同分区而出现不能使用的问题. 在创建软连接的文件中,修改一处文件另一处同 ...
- 最简单实用的MongoDB安装教程:在CentOS中使用 yum 安装MongoDB及服务器端配置详解
一.准备工作: 运行yum命令查看MongoDB的包信息 [root@vm ~]# yum info mongo-10gen (提示没有相关匹配的信息,) 说明你的centos系统中的yum源不包含M ...
- soapUI系列之—-06 testrunner实现自动化测试
TestRunner为soapUI自带------testrunner.bat/testrunner.sh 实现步骤: 1. 使用soapUI,针对接口文件创建测试用例. 2. 将测试用例保存至本地, ...
- int&boolean——Java和C的一点小差别
Java和C的差别非常多.只是预计这一点非常多人都不知道. 今天面试时碰到这么道C语言题 求执行结果 int x = -1; while(!x!=0){ cout<<x<<en ...
- 【翻译自mos文章】在12c中Create or Truncate Table时非常慢,等待事件为 DFS Lock Handle wait
来源于: Create or Truncate Table Slow in 12c While Waiting for DFS Lock Handle wait (文档 ID 2085308.1) A ...
Unity的Entity-Component-System实现的很美丽,很灵活.许多文章也对这样的组件实体的开发模式倍加推崇.由于它契合这么一条规则:优先使用组合而不是继承. 可是实际开发过程中,限制 ...
最近,我们网站的上新增了几个新功能,比如通过导航栏的QR Code可以下载App:通过Carousel的方式,显示多条信息. 以往这样的功能可能需要2-3个Sprints完成,但是现在这些功能都是在一 ...
Microsoft SQL Server 安装,卸载,系统服务,系统组件及系统数据库 1. Microsoft SQL Server 安装 通过单击下拉框,选择浏览,然后在Active Directo ...
最近会转载一些 MSSQL 基础相关的文章. 参考文献: http://www.cnblogs.com/xianspace/archive/2009/04/05/1429835.html 前言 今天在 ...
一.程序与用户交互(Java的入口方法-main方法): 运行Java程序时,都必须提供一个main方法入口:public static void main(String[] args){} publ ...
分词,顾名思义就是把词语分开,从哪里分开?当然是一大堆词语里了,一大堆词语是什么?是废话或者名言.这在数据库搜索时非常有用. 官方网站 http://www.phpbone.com/phpanalys ...
Java开源生鲜电商平台-财务系统模块的设计与架构(源码可下载) 前言:任何一个平台也好,系统也好,挣钱养活团队这个是无可厚非的,那么对于一个生鲜B2B平台盈利模式( 查看:http://www.cn ...
内置系统账户:Local system/Network service/Local Service 区别 学习使用 xp_cmdshell 的时候 发现必须 sqlserver 的服务运行在local ...
系统内部集成测试(System Integration Testing) SIT 用户验收测试(User Acceptance Testing) UAT SIT在前,UAT在后,UAT测完才可以上线
dp +路径输出 #include <cstdio> #include <cstdlib> #include <cmath> #include <stack& ...
数位dp #include <cstdio> #include <cstdlib> #include <cmath> #include <stack> ...
原文:http://www.open-open.com/code/view/1444211411979 java截屏 * 运行后将当前屏幕截取,并最大化显示. * 拖拽鼠标,选择自己需要的部分. * ...
我们知道,每一个公司都会有自己的工具包或公共包.这样的包就能够上传到公司的maven私服,就不用每一个人都去同步开发包了. 那么,怎么把本地项目打包并公布到私服呢?依照例如以下步骤就能够轻松完毕. 1 ...
设计.实施和维护 Oracle 数据库时,按优先次序排列的任务包括: 1. 确定数据库服务器硬件 2. 安装 Oracle 软件 3. 为数据库和安全策略制定计划 4. 创建.移植和打 ...
创建软连接的方式 #ln -s soure /file object 创建软连接是连接文件本身,可以跨分区建立软连接,不会应为不同分区而出现不能使用的问题. 在创建软连接的文件中,修改一处文件另一处同 ...
一.准备工作: 运行yum命令查看MongoDB的包信息 [root@vm ~]# yum info mongo-10gen (提示没有相关匹配的信息,) 说明你的centos系统中的yum源不包含M ...
TestRunner为soapUI自带------testrunner.bat/testrunner.sh 实现步骤: 1. 使用soapUI,针对接口文件创建测试用例. 2. 将测试用例保存至本地, ...
Java和C的差别非常多.只是预计这一点非常多人都不知道. 今天面试时碰到这么道C语言题 求执行结果 int x = -1; while(!x!=0){ cout<<x<<en ...
来源于: Create or Truncate Table Slow in 12c While Waiting for DFS Lock Handle wait (文档 ID 2085308.1) A ...