浅尝一下ECS(Entity Component System)(学习笔记)

参考文章:浅谈Unity ECS(一)Uniy ECS基础概念介绍:面向未来的ECS - 知乎 (zhihu.com)

视频链接:【青幻译制】GDC讲座系列之三 守望先锋的游戏架构和网络代码_哔哩哔哩_bilibili

云风的 BLOG: 浅谈《守望先锋》中的 ECS 构架 (codingnow.com)

游戏开发中的ECS架构-CSDN博客

一个典型的 ECS 框架 ↑

世界->是系统和实体的组合 -> 实体是一个组件的集合所对应的ID,组件仅仅用于储存游戏状态,而不具备行为,系统具有行为却不保存游戏状态

组件没有函数,系统没有成员变量

Entity Component System (ECS) 是一个 gameplay 层面的框架,它是建立在渲染引擎、物理引擎之上的,主要解决的问题是如何建立一个模型来处理游戏对象 (Game Object) 的更新操作。

这边最主要区别就是把对象上的数据和行为剥离,由专门的System来处理某一种行为,而不是每个对象在自己的一个更新函数中处理所有和自己相关的操作

Unity ECS基本概念

Entity的概念

它的意义在于生命期管理,这里是用 32bit ID 而不是指针来表示的,另外附着了渲染用到的资源 ID 。因为仅负责生命期管理,而不设计调用其上的方法,用整数 ID 更健壮。整数 ID 更容易指代一个无效的对象,而指针就很难做到。

Entity为ECS中基本的成员,实际上只是由一个Index和一个Version组成(Version只有在Entity被回收后会加1),其实际的Component数据存储在一个Chunk上(Unity ECS特有的数据类型),需要操作其Component数据时,根据其index到EntityDataManager中找到其所在的Chunk和IndexInChunk,取到对应的Component数据后进行操作。

public struct Entity : IEquatable<Entity>{public int Index;public int Version;......   }

Component的概念

component是Entity的一个属性,通常记成了IComponentISharedComponentData 接口的结构体(两个接口都为空接口,仅标记了类型)。一个 Entity 可以包含多个 Component ,记成了 ISharedComponentData 的数据会在多个 Entity 中共享,同时可以使用托管类型的成员,一般用来存放 GameObject 或 RenderMesh 等渲染相关的成员

一个Entity的Component可以在CreateEntity时指定,也可以使用一个ArcheType创建或从已有Entity复制来创建。同时已经创建的Entity还可以通过AddComponentRemoveComponent来动态进行Component的添加或删除(由于效率问题不推荐)。

Tips:Component可以用Proxy包装后直接挂在GameObject上,挂载多个Proxy的GameObject可以作为Prefab直接传入EntityManager.Instantiate来生成新的Entity,如:

// Create an entity from the prefab set on the spawner component.var prefab = spawnerData.prefab;var entity = EntityManager.Instantiate(prefab);

ArcheType的概念

ArcheType 是Unity ECS 中特有的概念,也是 Unity ECS 内存管理中的一个核心部分,许多重要操作都与此相关。ArcheType 是由几个固定 Component 组成的 Entity 原型

  • ArcheType管理所有属于它的Entity Component数据,对应数据存放在归属于它的chunk上
  • 可以通过ArcheType快速访问所有该类型的Entity Component数据
  • 拥有Component的Entity一定处在某个ArcheType的管理之下
  • ArcheType拥有缓存机制,第二次创建相同的ArcheType时会自动将现有的返回

我们可以使用EntityManager.CreateArchetype(params ComponentType[] types)来主动创建一个ArcheType,通过ArcheType可以直接调用EntityManager.CreateEntity(EntityArchetype archetype)来快速创建具有某一类特征的Entity。同时如果使用直接传入Components的方式来创建Entity时也会自动生成含有对应Component的ArcheType。

ComponentSystem的概念

ComponentSystem 为 System 在 Unity ECS 中的实现,一个 ComponentSystem 会对含有某些 Component 的 Entity 执行一些特定的操作,通常继承自 ComponentSystem    或          JobComponentSystem。区别是继承 ComponentSystem 只会在主线程执行,而继承自 JobComponentSystem 则可以利用 JobSystem 来进行多线程并发处理,但同时对应操作过程中的限制也更严格。在大部分情况下应当尽量使用 JobComponentSystem 来完成相关的操作,从而提升性能

多个不同的 ComponentSystem 可以在定义时通过 UpdateBefore ,UpdateAfter,UpdateBefored 等标签来控制其执行顺序,这会在一定程度上影响并发执行,通常只在必要时使用

一个 ComponentSystem 通常关注一个包含特定的 Component 组合的 Entity 集合(称为 Component Group)这个 ComponentGroup 集合可以通过 GetComponentGroup 主动获取

ComponentGroup m_Spawners;
//获取包含ObjectSpawner和Position两个Component的ComponentGroup
protected override void OnCreateManager()
{m_Spawners = GetComponentGroup(typeof(ObjectSpawner), typeof(Position));
}

也可以使用 IJobProcessComponentData 中定义和 RequireSubtractiveComponentAttribute 等标签自动注入(Inject),同样也会生成一个 ComponentGroup

//通过RequireComponentTagAttribute为JobComponentSystem添加额外的依赖项
//[RequireComponentTagAttribute(typeof(Object))]
//通过RequireSubtractiveComponentAttribute为JobComponentSystem添加额外的排除项
[RequireSubtractiveComponentAttribute(typeof(ObjectSpawner))]  
struct ObjectMove : IJobProcessComponentData<Position>
{......public void Execute(ref Position position){......}
}

数据存储相关

Chunk的概念

chunk 是Unity ECS 中特有的一个数据结构,在ECS部分代码中有大量使用,通常是指用来存放 Component 信息的 ArchetypeChunk,此外还有更一般的 Chunk 通过 ChunkAllocator 进行开辟,可以存放 ArcheType 中的各类型信息,大小和存储结构都与 ArchetypeChunk 不同,此处的 Chunk 特指存放 ArcheType 中Component 信息的 ArchetypeChunk。chunk 有以下几个特点:

  • EntityManager会将Component数据存放在固定的16kb大小的Chunk中(可以在Chunk定义中找到指定大小kChunkSize)
  • 每个Chunk结构包含了这个区块中内容的相关信息
  • 每个EntityArchetype都包括了一个Chunk的独特集合
  • 一个chunk只能存在于一个archetype
  • 一个ArchetypeChunk结构是一个到具体Chunk的指针

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

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

相关文章

机器学习—特征预处理和降维(四)

什么是特征预处理&#xff1f; 通过一些转换函数将特征数据转换成更加适合算法模型的特征数据过程 1包含内容 数值型数据的无量纲化&#xff1a; 归一化标准化 2特征预处理API sklearn. preprocessing为什么要进行归一化 or 标准化&#xff1f; 特征的单位或者大小相差较大…

neo4j使用详解(十八、java driver使用及性能优化<高级用法>——最全参考)

Neo4j系列导航&#xff1a; neo4j安装及简单实践 cypher语法基础 cypher插入语法 cypher插入语法 cypher查询语法 cypher通用语法 cypher函数语法 neo4j索引及调优 neo4j java Driver等更多 1.依赖引入 <dependency><groupId>org.neo4j.driver</groupId><…

Springboot+Vue项目-基于Java+MySQL的校园周边美食探索及分享平台系统(附源码+演示视频+LW)

大家好&#xff01;我是程序猿老A&#xff0c;感谢您阅读本文&#xff0c;欢迎一键三连哦。 &#x1f49e;当前专栏&#xff1a;Java毕业设计 精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; &#x1f380; Python毕业设计 &…

微信过期文件怎么恢复?四个高招助你轻松解决(2024新版)

“微信的文件未下载的情况下过期了&#xff0c;平时微信也没有登录在电脑上&#xff0c;之前也没有进行过数据备份&#xff0c;如何找回这个文件啊&#xff01;&#xff01;感谢回答&#xff01;” “急求&#xff0c;当时忘记点击下载&#xff0c;现在急用微信文件下载不了&a…

Excel 记录单 快速录入数据

一. 调出记录单 ⏹记录单功能默认是隐藏的&#xff0c;通过如下如图所示的方式&#xff0c;将记录单功能显示出来。 二. 录入数据 ⏹先在表格中录入一行数据&#xff0c;给记录单一个参考 ⏹将光标至于表格右上角&#xff0c;然后点击记录单按钮&#xff0c;调出记录单 然后点…

h5 笔记4 表格与表单

<table></table>设置表格&#xff1b; <tr></tr>设置行数&#xff1b; <td></td>设置列数&#xff1b; <caption></caption>设置表格标题&#xff1b; <th></th>设置列标题。 直列&#xff1a;column&#xf…

1.16 LeetCode总结(基本算法)动态规划2

70. 爬楼梯 首先想到的是递归&#xff1a; // 递归 int climbStairs(int n) {if (n 1) {return 1;} else if (n 2) {return 2;}return climbStairs(n - 1) climbStairs(n - 2); }我们先来看看这个递归的时间复杂度吧&#xff1a; 递归时间复杂度 解决一个子问题时间*子问…

蓝桥杯:握手问题和小球反弹问题

试题 A: 握手问题 本题总分&#xff1a; 5 分 【问题描述】 小蓝组织了一场算法交流会议&#xff0c;总共有 50 人参加了本次会议。在会议上&#xff0c; 大家进行了握手交流。按照惯例他们每个人都要与除自己以外的其他所有人进行一次握手&#xff08;且仅有一次&#x…

阿里云ECS迁移至AWS EC2,九河云详细教程

在客户在求更大的海外市场&#xff0c;综合考虑后决定选择AWS云&#xff0c;但对迁移方面不太了解&#xff0c;甚至比较担心如果到AWS云是否业务要从0开始&#xff1f;本文九河云将为您介绍如何将阿里云ECS平滑迁移至AWS。 工具介绍 AWS Application Migration Service &…

【Linux网络编程】TCP协议

TCP协议 1.TCP协议段格式4位首位长度序号和确认序号16位窗口大小6个标志位 2.确认应答机制3.超时重传机制4.连接管理机制如何理解连接如何理解三次握手如何理解四次挥手 5.流量控制6.滑动窗口7.拥塞控制8.延迟应答9.捎带应答10.面向字节流11.粘包问题12.TCP异常情况13.TCP小结1…

基于Springcloud可视化项目:智慧工地可视化大数据云平台源码

目录 技术架构 智慧工地系统在实际推行过程中遇到的问题 智慧工地接纳程度较低 基础设施条件有待完善 智慧工地整体生态尚未完善 智慧工地平台各功能模块 施工过程工信程息信管息理管模理块 人员管理模块 生产管理模块 技术管理模块 质量管理模块 安全管理模块 绿…

计算机网络书籍--《网络是怎样连接的》阅读笔记

第一章 浏览器生成信息 1.1 生成HTTP请求信息 1.1.1 URL Uniform Resource Locator, 统一资源定位符。就是网址。 不同的URL能够用来判断使用哪种功能来访问相应的数据&#xff0c;比如访问Web服务器就要用”http:”&#xff0c;而访问FTP服务器用”ftp:”。 FTP&#xff…