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

news2024/11/29 2:47:16

参考文章:浅谈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.coloradmin.cn/o/1599111.html

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

相关文章

消息队列和分布式消息队列

文章目录 分析系统现状不足中间件消息队列什么是消息队列&#xff1f;应用场景消息队列的模型为什么不直接传输&#xff0c;而要用消息队列&#xff1f;为什么要用消息队列&#xff1f;消息队列的缺点&#xff1f; 分布式消息队列分布式消息队列的优势&#xff1f;消息队列应用…

PLC远程通信:实现工业自动化的关键技术

在当今高度信息化和自动化的时代&#xff0c;工业领域对于实时数据的准确传输和迅速响应提出了更高要求。而PLC(可编程逻辑控制器)远程通信技术&#xff0c;正是能够实现工业自动化的关键技术之一。 首先&#xff0c;我们需要了解PLC远程通信的原理。PLC作为一种专用计算机控制…

设计模式代码实战-组合模式

1、问题描述 小明所在的公司内部有多个部门&#xff0c;每个部门下可能有不同的子部门或者员工。 请你设计一个组合模式来管理这些部门和员工&#xff0c;实现对公司组织结构的统一操作。部门和员工都具有一个通用的接口&#xff0c;可以获取他们的名称以及展示公司组织结构。…

学习BOM

目录 前言: 1. BOM组成&#xff1a; 1.1Window 对象&#xff1a; 1.1Location 对象&#xff1a; 1.2Navigator 对象&#xff1a; 1.2.1 navigator 对象包含了关于浏览器的信息包括&#xff1a; 1.3History 对象&#xff1a; 1.4常用的history的方法和属性: 1.4Document…

氟化钙与盐酸反应

结论&#xff1a;可以反应 参考链接 为什么盐酸,硝酸不能溶解氟化钙呢?氢氟酸可是弱酸啊。。。_百度知道 (baidu.com)https://zhidao.baidu.com/question/421110040.html特此记录 anlog 2024年4月16日

中医圆运动规律

目录 人体圆运动营气在十二经脉的运行规律子午流注与圆运动升降结合图 人体圆运动 营气在十二经脉的运行规律 营气在脉中&#xff0c;卫气在脉外 这个顺序也是子午流注的顺序 子午流注与圆运动升降结合图

【论文阅读02】一种基于双通道的水下图像增强卷积神经网络

来源&#xff1a;海洋论坛▏一种基于双通道的水下图像增强卷积神经网络 当前不会的 一、背景&#xff1a; 水下图像增强方法包含有无水下成像模型的水下图像增强方法、基于水下成像模型的水下图像恢复方法、水下成像模型与深度学习相结合的方法以及完全采用深度学习的方…

数据结构与算法——22.哈希算法

这篇文章我们来讲一下哈希表中较为关键的部分——哈希算法 目录 1.哈希算法的介绍 2.hash算法的使用 2.1 Object.hashCode 2.2 String.hashCode 3.关于哈希表及哈希算法的一些思考 1.哈希算法的介绍 问题&#xff1a;什么是哈希算法&#xff1f;哈希算法有哪些&#xff…

【算法一则】做算法学数据结构 - 简化路径 - 【栈】

目录 题目栈代码题解 题目 给你一个字符串 path &#xff0c;表示指向某一文件或目录的 Unix 风格 绝对路径 &#xff08;以 ‘/’ 开头&#xff09;&#xff0c;请你将其转化为更加简洁的规范路径。 在 Unix 风格的文件系统中&#xff0c;一个点&#xff08;.&#xff09;表…

兔C_Java集:Java 语言简介

文章目录 1. Java简介历史简介问&#xff1a;Oracle 为什么收购 SUN 公司关于三个分支语言特性&#xff1a; 2. JDK 的安装与配置安装的官网链接配置环境变量 3. 第一个Java程序4. 第一个程序解释关于类的定义 5. CLASSPATH命令自动配置CLASSPATH 与 JVM 的关系CLASSPATH 的手动…

OM3 与 OM4:主要区别和实际应用

OM3 和 OM4 都是激光优化的多模光纤&#xff0c;具有 50/125μm 光纤芯&#xff0c;专为满足 ISO 11801 标准而开发。它们在光纤连接器和应用场景上具有相似性&#xff0c;这往往会导致用户之间的混淆。这些光纤主要设计用于数据中心、局域网 &#xff08;LAN&#xff09; 和其…

500以内的不入耳运动耳机推荐,首推五大业内顶级优品

不入耳式运动耳机因其独特的佩戴方式和设计&#xff0c;能够在运动过程中保持对周围环境的警觉&#xff0c;避免因音乐沉浸而忽视潜在的安全隐患&#xff0c;同时它们还能有效减少对耳道的压迫&#xff0c;让运动更加舒适自在&#xff0c;接下来&#xff0c;就让我为大家推荐一…

MAC系统安装PHP、Java、Python、mysql、Composer等环境无权限问题的详细操作方法说明。

本篇文章主要讲解MAC系统安装PHP、Java、Python、mysql、Composer等环境无权限问题的详细操作方法说明。通过本篇文章你可以快速掌握brew安装相对应环境的能力。 作者&#xff1a;任聪聪 日期&#xff1a;2024年4月12日 一、brew介绍及安装说明 官网地址&#xff1a;https://b…

分布式数据库Polardb-X架构及特点

PolarDB-X架构 计算节点&#xff08;Compute Node&#xff0c;CN&#xff09;是系统的入口&#xff0c;采用无状态设计的sql引擎提供分布式路由和计算&#xff0c;包括SQL解析器、优化器、执行器等模块。负责数据分布式路由、计算及动态调度&#xff0c;负责分布式事务2PC协调…

VLAN Mapping原理描述

基本原理 路由器收到带Tag的数据报文后&#xff0c;根据配置的VLAN Mapping方式&#xff0c;决定替换外层Tag中的VLAN ID或优先级&#xff1b;然后进入MAC地址学习阶段&#xff0c;根据源MAC地址映射后的VLAN ID刷新MAC地址表项&#xff1b;根据目的MAC映射后VLAN ID查找MAC地…

【电控笔记2.3】速度回路+系统延迟

2.3.1速度回路pi控制器设计 pi伯德图近似设计(不考虑延时理想情况下) Tl:负载转矩 PI控制器的转折频率:Ki/Kp

用海豚调度器定时调度从Kafka到HDFS的kettle任务脚本

在实际项目中&#xff0c;从Kafka到HDFS的数据是每天自动生成一个文件&#xff0c;按日期区分。而且Kafka在不断生产数据&#xff0c;因此看看kettle是不是需要时刻运行&#xff1f;能不能按照每日自动生成数据文件&#xff1f; 为了测试实际项目中的海豚定时调度从Kafka到HDF…

Django中的定时任务与后台任务队列的实践【第164篇—Django】

&#x1f47d;发现宝藏 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。【点击进入巨牛的人工智能学习网站】。 在Web开发中&#xff0c;处理定时任务和后台任务队列是很常见的需求。Django作为一个功能强…

隐私保护?还是安全漏洞?邮箱分身双重身份及创建攻略解析!

很多人只知道微信、QQ等应用分身&#xff0c;对于邮箱分身并不是很了解。邮箱分身和他们的不同点在于我们直接在原有邮箱的基础上创立新的虚拟邮箱地址&#xff0c;并且密码一致&#xff0c;在我们需要运营多个社交媒体账号或者管理多个项目的情况下&#xff0c;邮箱分身是一个…

为什么物联网安全性引发了对身份盗窃的担忧?

物联网是连接互联网的设备和传感器的统称&#xff0c;它代表了一个新的技术时代。这种硬件利用了连接性、硬件、小型化、云计算、数据处理、集成等方面的进步&#xff0c;为消费者和企业带来了好处&#xff0c;同样的物联网方面的威胁也是不断的在增加。 物联网是连接互联网的设…