继承体系的问题,为什么要用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



EntityAdmin是个World,存储了一个所有System的集合,和一个所有实体的哈希表(ID为unit32)。

单例组件

示例:命中处理System

  • ModifyHealthQueue组件,记录实体身上所有伤害和治疗效果
  • MovementState组件,移动数据处理
  • 一组Utility函数处理错误纠错,回滚相关Component

几个建议

  • System定义组件的组合时,可以把组件标记为只读
  • 实体生命周期建议立即创建,延时销毁
  • 某些遗留子系统不能接入ECS时,就不要强行接入,保持子系统的整洁
  • 事实证明,网络同步真的很复杂,所以必须尽可能的与引擎其余部分解耦,ECS是解决这个问题的好办法。

Unity中的ECS

在PackageManager中下载Entities

参考

组件-实体-系统 Entiy-Compoent-System ECS架构整理的更多相关文章

  1. Unityclient框架笔记二(组件实体开发模式的思考)

    Unity的Entity-Component-System实现的很美丽,很灵活.许多文章也对这样的组件实体的开发模式倍加推崇.由于它契合这么一条规则:优先使用组合而不是继承. 可是实际开发过程中,限制 ...

  2. 设计系统(Design System),设计和开发之间的“DevOps”

    最近,我们网站的上新增了几个新功能,比如通过导航栏的QR Code可以下载App:通过Carousel的方式,显示多条信息. 以往这样的功能可能需要2-3个Sprints完成,但是现在这些功能都是在一 ...

  3. 02Microsoft SQL Server 安装,卸载,系统服务,系统组件及系统数据库

    Microsoft SQL Server 安装,卸载,系统服务,系统组件及系统数据库 1. Microsoft SQL Server 安装 通过单击下拉框,选择浏览,然后在Active Directo ...

  4. (转)内置系统账户:Local system/Network service/Local Service 区别

    最近会转载一些 MSSQL 基础相关的文章. 参考文献: http://www.cnblogs.com/xianspace/archive/2009/04/05/1429835.html 前言 今天在 ...

  5. 疯狂java笔记(五) - 系统交互、System、Runtime、Date类

    一.程序与用户交互(Java的入口方法-main方法): 运行Java程序时,都必须提供一个main方法入口:public static void main(String[] args){} publ ...

  6. php 分词 —— PHPAnalysis无组件分词系统

    分词,顾名思义就是把词语分开,从哪里分开?当然是一大堆词语里了,一大堆词语是什么?是废话或者名言.这在数据库搜索时非常有用. 官方网站 http://www.phpbone.com/phpanalys ...

  7. Java开源生鲜电商平台-财务系统模块的设计与架构(源码可下载)

    Java开源生鲜电商平台-财务系统模块的设计与架构(源码可下载) 前言:任何一个平台也好,系统也好,挣钱养活团队这个是无可厚非的,那么对于一个生鲜B2B平台盈利模式( 查看:http://www.cn ...

  8. [转帖]内置系统账户:Local system/Network service/Local Service 区别

    内置系统账户:Local system/Network service/Local Service 区别 学习使用 xp_cmdshell 的时候 发现必须 sqlserver 的服务运行在local ...

  9. 系统内部集成测试(System Integration Testing) SIT 用户验收测试(User Acceptance Testing)

    系统内部集成测试(System Integration Testing) SIT 用户验收测试(User Acceptance Testing) UAT SIT在前,UAT在后,UAT测完才可以上线

随机推荐

  1. Codeforces 645D Robot Rapping Results Report【拓扑排序+二分】

    题目链接: http://codeforces.com/problemset/problem/645/D 题意: 给定n个机器人的m个能力大小关系,问你至少要前几个大小关系就可以得到所有机器人的能力顺 ...

  2. poj——2771 Guardian of Decency

    poj——2771    Guardian of Decency Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 5916   ...

  3. [Bzoj4182]Shopping(点分治)(树上背包)(单调队列优化多重背包)

    4182: Shopping Time Limit: 30 Sec  Memory Limit: 128 MBSubmit: 374  Solved: 130[Submit][Status][Disc ...

  4. 包装类Float中为什么有两个常量来表示最小值

    1)问:包装类Float中为什么有两个常量来表示最小值:MIN_VALUE和MIN_NORMAL ① MIN_VALUE:最小正非零值常量,是非规格化浮点数所能表示的最小值.值为 3.4E-45 的常 ...

  5. 【转】ubuntu 下安装mongodb php 拓展的方法

    按照上面的方法安装成功之后,写一个 mongodb 的php测试脚本,用来测试是否可以 正确连接上mongodb ,并查询结果. 参考:http://php.net/manual/en/class.m ...

  6. volatile关键字解析&内存模型&并发编程中三概念

    原文链接: http://www.cnblogs.com/dolphin0520/p/3920373.html volatile这个关键字可能很多朋友都听说过,或许也都用过.在Java5之前,它是一个 ...

  7. Deepin-键盘快捷键

    是不是很happy呢? 可以用键盘替代鼠标点点点了! 1.鼠标移到右下角 2.下翻找到"快捷键" 3.自定义一个 4.示例(首先编写个简单的Shell) 程序一般放在/usr/bi ...

  8. I2C上拉电阻取值范围

    I2C总线是微电子通信控制领域中常用的一种总线标准,具备接线少,控制简单,速率高等优点.在I2C电路中常见的上拉电阻有1k.1.5k.2.2k.4.7k.5.1k.10k等等,但是应该如何根据开发要求 ...

  9. (WPF)附加属性

    <Window x:Class="DeepXAML.MainWindow" xmlns="http://schemas.microsoft.com/winfx/20 ...

  10. PHP出现Warning: A non-numeric value encountered问题的原因及解决方法

    本文介绍php出现Warning: A non-numeric value encountered问题,用实例分析出现这种错误的原因,并提供避免及解决问题的方法. <?php error_rep ...