ECS框架学习

DOTS

Unity DOTS是Unity官方基于ECS架构开发的一套包含Burst编辑器和JobSystem的技术栈,它旨在充分利用多核处理器的特点,充分发挥ECS的优势。
在这里插入图片描述

安装

Entities、Burst、Jobs、Hybrid Renderer(必选,用于DOTS的渲染相关)、Unity Physics(非必选,用于DOTS的高性能物理组件)

com.unity.Entities
com.unity.rendering.hybrid

ECS框架

实体(Entity):ID和组件列表
组件(Component):存储Data
系统(System):对象关联的Component进行操作
适用情况:需要处理超多对象的同屏渲染问题,如戴森球计划;需要处理超多对象的管理和操作,如FPS游戏。

传统Unity开发,通常是把逻辑脚本挂载到GameObject上,很多时候还可能挂载多个不同功能的逻辑脚本。而ECS采用面向数据的方法,Entity代替了传统的GameObject的概念,Component则保留了传统组件的数据部分,所有逻辑交由System处理。写ECS的基本思路就是创建Component、创建Entity、编写System处理逻辑。

System可以重写OnUpdate函数,大家可以把它看成是MonoBehaviour的Update函数。这就是之前提到的,ECS把实体的逻辑专门放到System里处理了。OnUpdate函数也是会每帧调用一次的。

Component继承IComponentData

Entity

创建方式

  • [GenerateAuthoringComponent] 自动将组件转换成实体
  • [RequiresEntityConversion] 通过EntityManager的AddComponentData将组件附加到实体上
  • 通过Prefab创建实体 *方便
  • EntityCommandBufferSystem *灵活

Component

Component需要继承IComponentData

其他组件类型

ISharedComponentData(共享组件) // 生成大量相同怪物
ChunkComponent(块组件)
ISystemStateComponent(状态组件) // 处理回调事件
ISystemStateSharedComponentData(状态共享组件)
IBufferElementData(动态队列/缓冲区/数组)

System

System需要继承ComponentSystemJobComponentSystem

  • ComponentSystem更适合旧项目迁移到ECS框架,类似于Monobehaviour,但ECS的性能在多线程下才能发挥到最大
  • JobComponentSystem配合各种Job(IJobForEach、IJobChunk等),可以方便地实现并行(多线程、多核)执行逻辑
    System中可以重写了OnUpdate(),该函数每帧调用一次,类似mono的Update()。System相当于将一定的逻辑封装起来,例如RunSystem、JumpSystem等,那对应的问题就是System如何知道哪些Entity需要执行逻辑,答案就是筛选,而筛选条件就是Component。

筛选方式

  • Entities.ForEach
  • IJobChunk
  • IJobForEachWithEntity
  • EntityQuery *灵活 All Any None

Entity Debuger

不同于传统Debug,ECS框架下需要用Entity Debuger进行调试,Unity菜单的Window->Analysis->EntityDebugger,可以打开ECS的调试窗口

Chunk和Archetype

对于拥有相同Component的Entity,ECS采用Chunk结构统一存储,例如下图中的EntityA和EntityB
在这里插入图片描述
Chunk不能无限存储Entity,当Entity数量过多时,就需要用新的概念Archetype来统一保存Chunk。
在这里插入图片描述

World

ECS会自动创建一个默认世界,包含了实体管理器(EntityManager)以及项目中所有可用的系统(System)。

系统分组(ComponentSystem Group)

System用来处理游戏逻辑,游戏逻辑肯定就会涉及到先后顺序,为了解决这类问题,System的OnUpdate函数的执行是有先后顺序的。

// ECS默认分组
InitializationSystemGroup(负责初始化工作的系统分组)
SimulationSystemGroup(负责逻辑运算的系统分组)
PresentationSystemGroup(负责图形与渲染工作的系统分组)

使用特性(Attribute)调整System执行顺序

UpdateInGroup:指定当前System在哪个分组下
UpdateBefore:指定当前System在哪个System之前执行
UpdateAfter:指定当前System在哪个System之后执行

EntityCommandBuffer

JobComponentSystem配合各种Job(IJobChunk等),可以方便地实现并行(多线程、多核)执行逻辑。多线程逻辑中会出现数据一致性的问题,ECS规定,以下行为都不能在Job中处理:创建实体(Create Entities)、销毁实体(Destroy Entities)、给实体添加组件(Add Components)、删除实体的组件(Remove Components),需要采用EntityCommandBuffer提前或延迟执行。
每一个系统分组下都有两个EntityCommandBufferSystem,并且分别都是Begin和End对应的,通过World获取System。
笨木头的博客里讲到“在JobComponentSystem中,如果Job没有筛选出实体数据,那么,OnUpdate是不会被调用的”,这也就解释了为什么有些system最后会执行DestoryEntity操作。这就是面向数据编程的关键,程序根据数据筛选实体,执行逻辑,删除数据保证后面筛选不到。(我需要执行逻辑就添加,执行完了删掉,完全是数据有无在控制逻辑的有无)。
EntityCommandBufferSystem每次执行队列的任务后,都会清空,所以不存在重复执行的问题。


参考链接

官方Demo ECS Samples
笨木头与游戏开发 博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/569582.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

辅助排序和Mapreduce整体流程

一、辅助排序 需求:先有一个订单数据文件,包含了订单id、商品id、商品价格,要求将订单id正序,商品价格倒序,且生成结果文件个数为订单id的数量,每个结果文件中只要一条该订单最贵商品的数据。 思路&#xf…

[读书笔记] 史玉柱自述:我的营销心得

与下属的关系 从玩家角度设定目标 目标感的设计 论随机性 在前15分钟留住玩家 实际观察玩家对于游戏的翻译反应 好游戏是改出来的 注重细节 决策民主、责任人制度 论简单与复杂的关系 游戏经济中的投放与回收 避免进入降低压力的怪圈 创业初期的股份分配 单个行业…

记一次面试腾讯的奇葩经历

阅读本文大概需要 2.8 分钟。 作者:黄小斜 文章来源:微信公众号【程序员江湖】 ​ 上回说到,我腾讯面试出师不利,简历随即进入备胎池,不过没过多久,转机还是来了。 大概是一周之后,我的电话响起…

foot

码云链接&#xff1a;https://gitee.com/zyyyyyyyyyyy/codes/rcfdzmin4a82v975pl1ko47 效果图&#xff1a; 原网站截图&#xff1a; 源代码&#xff1a; <!DOCTYPE html><html><head><meta charset"UTF-8"><title></title><s…

Taro项目遇到的问题

1. https://taro-ui.aotu.io/#/docs/questions 请在Taro项目根目录找到 config/index.js 文件中的h5项&#xff0c;添加如下&#xff1a; h5: {...esnextModules: [taro-ui] } 2. 原则&#xff1a;少什么就装什么 少了 babel-plugin-transform-decorators-legacy &#xff0c;那…

严重: StandardServer.await: create[localhost:8005]

①看看任务管理器&#xff0c;是否打开了多个Tomcat程序 如果是&#xff0c;关闭其中一个 ②可能是端口冲突 1、将tomcat安装目录下的conf/server.xml中的8005端口号改为其它的端口号。&#xff08;不建议&#xff0c;因为会衍生出其他错误&#xff09; 2、将正在使用的8005端…

java里short,int,long,float,double范围及可写位数

一、取值范围 1、int二进制位数&#xff1a;32 包装类&#xff1a;java.lang.Integer最小值&#xff1a;Integer.MIN_VALUE -2147483648 &#xff08;-2的31次方&#xff09;最大值&#xff1a;Integer.MAX_VALUE 2147483647 &#xff08;2的31次方-1&#xff09;2、short 二…

第六周编程总结

6-1 求两数平方根之和 &#xff08;10 分) 函数fun的功能是&#xff1a;求两数平方根之和&#xff0c;作为函数值返回。例如&#xff1a;输入12和20&#xff0c;输出结果是&#xff1a;y 7.936238。 函数接口定义&#xff1a; double fun (double a, double b); 其中 a和 b是用…

【CH5105】Cookies

也是一道线型动态规划的好题…… 读入每个人的贪婪度之后&#xff0c;对其按照从大到小的顺序排序&#xff0c;定义状态f[i][j]为前i个人&#xff08;排序后&#xff09;分j个饼干的答案&#xff0c;那么答案为f[n][m],考虑状态转移方程。 1、若给第i个人的饼干数大于1 &#x…

sharing-jdbc实现读写分离及分库分表

需求&#xff1a; 分库&#xff1a;按业务线business_id将不同业务线的订单存储在不同的数据库上&#xff1b; 分表&#xff1a;按user_id字段将不同用户的订单存储在不同的表上&#xff0c;为方便直接用非分片字段order_id查询&#xff0c;可使用基因法&#xff1b; 读写分离&…

性能测试学习05_lr(根据接口文档写脚本+参数化)

1、根据接口文档写脚本&#xff0c;函数&#xff08;web_custom_request&#xff09;&#xff0c;完成get&#xff0c;post请求&#xff08;注册&#xff0c;登录&#xff09; 代码&#xff1a; Action() {lr_save_string("请填写你的IP", "IP");//注册/*w…

java 历届试题 合根植物

问题描述w星球的一个种植园&#xff0c;被分成 m * n 个小格子&#xff08;东西方向m行&#xff0c;南北方向n列&#xff09;。每个格子里种了一株合根植物。这种植物有个特点&#xff0c;它的根可能会沿着南北或东西方向伸展&#xff0c;从而与另一个格子的植物合成为一体。如…

(软件项目管理)项目会议纪要模板

备注&#xff1a; 七: 1、报送&#xff1a;把整理好的会议的内容报给上级的相关部门。2、主送&#xff1a;把整理好的会议的内容发放给下级相关部门。3、抄送&#xff1a;把整理好的会议的内容送给相关的同级单位或不相隶属的单位。

EVE-NG安装步骤

首先&#xff0c;需要EVE-NG客户端工具包 1、 1.1部分图 点击next 2、 保持默认全选&#xff0c;点击next 3、 点击install 4、选择I accept the agreement&#xff0c;点击next 5、下一步&#xff0c;继续点击next 6、选定安装位置&#xff0c;不清楚就默认C盘&#x…

第三次实验

Part1: 验证性内容 在循环中使用控制语句continue和break&#xff0c; 其功能区别是什么&#xff1f; continue是停止当前语句的执行&#xff0c;回到第一条语句继续执行&#xff0c;而break是直接结束循环。 在两层嵌套循环中&#xff0c;内层循环中如果出现continue&#xf…

Linux shell 中$() ` `,${},$[] $(()),[ ] (( )) [[ ]]作用与区别

看到几篇博客&#xff0c;觉得写的不错 原文&#xff1a;https://blog.csdn.net/x1269778817/article/details/46535729 和http://blog.zol.com.cn/2322/article_2321763.html $()和 &#xff1a; 在 bash shell 中&#xff0c;$( ) 与 (反引号) 都是用来做命令替换用(c…

WPF编程,将控件所呈现的内容保存成图像的一种方法。

WPF编程&#xff0c;将控件所呈现的内容保存成图像的一种方法。 原文:WPF编程&#xff0c;将控件所呈现的内容保存成图像的一种方法。版权声明&#xff1a;我不生产代码&#xff0c;我只是代码的搬运工。 https://blog.csdn.net/qq_43307934/article/details/87278138 实现只对…

二维数组(声明以及遍历)

首先图面理解二维数组&#xff08;数组里面的元素不是字符或者数字类型而是另外一个数组&#xff09;! 一&#xff0c;二维数组的声明 int[ ] [ ] arr; 初始化一个能存3个一维数组的二维数组 arr new int [3] [ ]; (此时只声明了一个二维数组的空间&#xff0c;并没有声明一维…

shell中各种括号()、(())、[]、[[]]、{}的作用

转自&#xff1a;http://blog.csdn.net/ztf312/article/details/52317571 技巧小结&#xff1a; 字符串比较用双中括号[[ ]]&#xff1b;算数比较用单中括号[ ]——左右留空格 算数运算用双小括号(( )) &#xff1b;shell命令及输出用小括号( )——左右不留空格 快速替换用…