当前位置: 首页 > news >正文

Unity DOTS系列之IJobChunk来迭代处理数据

最近DOTS发布了正式的版本, 我们来分享一下System中如何在System中使用IJobChunk来迭代处理World中的数据,方便大家上手学习掌握Unity DOTS开发。

再回顾一次基于ArcheType Chunk内存管理

我们先再次回顾以下基于ArcheType的Chunk内存管理。每一类Entity都是由一些列的ComponentData组合而成的,这个组合我们使用ArcheType来进行描述。同一种ArcheType的Entity具有相通的内存大小与布局,存放在chunk里面。每个chunk只会存放同一种ArcheType类型的Entity的组件数据。每个chunk的大小是16kb。里面并排存放着每个Entity的组件数据。如下所示:

对惹,这里有一个游戏开发交流小组,大家可以点击进来一起交流一下开发经验呀!

===============================
ArchType1:
chunk1【e1(c1c2),e2(c1c2),e3(c1c2)】
chunk2【e4(c1c2),e5(c1c2),e6(c1c2)】
...
======================
ArchType2:
chunk1【e1(c3c4),e2(c3c4),e3(c3c4)】
chunk2【e4(c3c4),e5(c3c4),e6(c3c4)】
...
===============================
ArchType3: 
chunk1【e1(c5c6),e2(c5c6),e3(c5c6)】
chunk2【e3(c5c6),e4(c5c6),e5(c5c6)】
...
===============================

使用IjobChunk的主要流程

在DOTS中迭代处理Entity的组件数据先找到对应符合条件的ArcheType,然后再找到ArcheType对应的所有的Chunks,再遍历每个Chunk里面的每个Entity的组件数据。有了这个思路以后,我们先来看下如何来使用IJobChunk机制来进行数据迭代。步骤如下:

  1. 定义一个EntityQuery对象,它根据赛选条件而生成,当IJobChunk来筛选Entity的时候就基于这个对象的筛选条件。EntityQuery对象是基于EntityQueryBuilder对象创建出来。EntityQueryBuilder负责将筛选条件转成最后的EntityQuery对象。示例代码如下:
    public partial class UpdateTranslationFromVelocitySystem : SystemBase{EntityQuery query;protected override void OnCreate(){// Set up the queryquery = new EntityQueryBuilder(Allocator.Temp).WithAllRW<ObjectPosition>().WithAll<VelocityVector>().Build(this);}
  1. 定义一个继承IJobChunk接口的Job结构体,并实现Execute接口。
public struct UpdateTranslationFromVelocityJob : IJobChunk {
public void Execute(in ArchetypeChunk chunk, 
int unfilteredChunkIndex, 
bool useEnabledMask, 
in v128 chunkEnabledMask)}
  1. 定义在Job中Execute中所使用的数据,这些数据在System Update迭代的时候传入。IJobChunk迭代处理数据的时候都是一个一个Chunk来处理的,每个Chunk调用一次Execute函数。在Execute函数中你需要什么样的数据就可以定义在Job的结构体里面。
public struct UpdateTranslationFromVelocityJob : IJobChunk{public ComponentTypeHandle<VelocityVector> VelocityTypeHandle;public ComponentTypeHandle<ObjectPosition> PositionTypeHandle;public float DeltaTime;       public void Execute(in ArchetypeChunk chunk, 
int unfilteredChunkIndex, 
bool useEnabledMask, 
in v128 chunkEnabledMask){}}

利用ComponentTypeHandle可以把chunk内存块里面所有的对应的组件的数据放到NativeArray里面给Execute迭代使用。普通的数据可以直接定义即可。

  1. 实现Interface IjobChunk的Execute函数的具体迭代逻辑,用于具体的处理。处理组件数据的时候,基于ComponentTypeHandle把Chunk里面的组件数据获取到一个NativeArray里面。Execute有4个参数:
  • chunk,类型是ArcheTypeChunk,就是我们的chunk内存块,存放数据地方;
  • unfilteredChunkIndex: 我们当前chunk,所在所有chunk的索引;
  • bool useEnbaleMask, in v128 chunkEnableMask, 是enableable component的bitmap,给我们查询使用。

在Execute里面我们使用ChunkEntityEnumerator来遍历chunk里面的每个entity的Component,参考代码如下:

NativeArray<VelocityVector> velocityVectors = chunk.GetNativeArray(ref VelocityTypeHandle);NativeArray<ObjectPosition> translations = chunk.GetNativeArray(ref PositionTypeHandle);var enumerator = new ChunkEntityEnumerator(useEnabledMask, chunkEnabledMask, chunk.Count);while(enumerator.NextEntityIndex(out var i)){float3 translation = translations[i].Value;float3 velocity = velocityVectors[i].Value;float3 newTranslation = translation + velocity * DeltaTime;translations[i] = new ObjectPosition() { Value = newTranslation };}
  1. 在System中来使用IJobChunk,进行执行。当JobChunk的结构体定义好以后,我们就可以在System中使用它们,在System的Update中定义一个结构体对象,把JobChunk结构体中的数据初始化好,然后调用JobChunk的执行函数。执行函数有三个接口,分别如下:
  • Run: 执行当前的job(job chunk 的execute)是在当前线程(system的update迭代所在的线程);
  • Shedule: 就是会在另外一个线程来处理我们的Excute,按照顺序一个一个来处理; chunk1, chunk2, chunk3….
  • SheduleParallel: 并发处理, 可以多个线程同时并发处理多个chunk, 线程1 chunk1, 线程2 处理chunk2 , …..

按照这5个步骤,来定义与使用IJobChunk来计算迭代游戏逻辑与数据。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • python教程修订版
  • 当电子设计竞赛照进生活!
  • 4G 网络下资源加载失败?一次运营商封禁 IP 的案例分享
  • 【RabbitMQ】死信队列、延迟队列
  • 什么是电商云手机?可以用来干什么?
  • 2025年SEO策略:如何优化您的知识库?
  • ComfyUI中缺失节点安装一点小小注意事项
  • 详解常见排序
  • 三丰云免费虚拟主机及免费云服务器评测
  • OpenEuler22.03 LTS-SP1 开启SSH的X11 Forwarding,并使用Edge浏览器
  • ‌[AI问答] Auto-sklearn‌ 与 scikit-learn 区别
  • 「数组」离散化 / Luogu B3694(C++)
  • [晕事]今天做了件晕事45 ssh 远程执行命令与>
  • 828华为云征文 | 将Vue项目部署到Flexus云服务器X实例并实现公网访问
  • 2.3 数据通信基础知识
  • java2019面试题北京
  • JavaScript 基本功--面试宝典
  • Java的Interrupt与线程中断
  • Java多线程(4):使用线程池执行定时任务
  • open-falcon 开发笔记(一):从零开始搭建虚拟服务器和监测环境
  • 从零开始的webpack生活-0x009:FilesLoader装载文件
  • ​Spring Boot 分片上传文件
  • #HarmonyOS:Web组件的使用
  • #微信小程序(布局、渲染层基础知识)
  • #中的引用型是什么意识_Java中四种引用有什么区别以及应用场景
  • (2)nginx 安装、启停
  • (c语言+数据结构链表)项目:贪吃蛇
  • (笔试题)合法字符串
  • (二十三)Flask之高频面试点
  • (论文阅读32/100)Flowing convnets for human pose estimation in videos
  • (转)如何上传第三方jar包至Maven私服让maven项目可以使用第三方jar包
  • .360、.halo勒索病毒的最新威胁:如何恢复您的数据?
  • .bat批处理(八):各种形式的变量%0、%i、%%i、var、%var%、!var!的含义和区别
  • .NET/C# 异常处理:写一个空的 try 块代码,而把重要代码写到 finally 中(Constrained Execution Regions)
  • .NET/C# 在 64 位进程中读取 32 位进程重定向后的注册表
  • .py文件应该怎样打开?
  • [ IDE ] SEGGER Embedded Studio for RISC-V
  • [ vulhub漏洞复现篇 ] Hadoop-yarn-RPC 未授权访问漏洞复现
  • [AIGC] SQL中的数据添加和操作:数据类型介绍
  • [ai笔记4] 将AI工具场景化,应用于生活和工作
  • [C++] vector list 等容器的迭代器失效问题
  • [C++]: std::move
  • [CUDA 学习笔记] CUDA kernel 的 grid_size 和 block_size 选择
  • [GDOUCTF 2023]<ez_ze> SSTI 过滤数字 大括号{等
  • [Qualcomm][GPIO]高通芯片引脚相关知识记录
  • [SoapUI] SoapUI学习视频地址
  • [Swift] Enum 好用, Enum 可以更易用
  • [备用] VS中生成报表
  • [创业之路-42] 创业是只有一小部分人活下来的游戏,探究创业失败的20个主要原因与提高成功率
  • [纯干货] MySQL索引背后的数据结构及算法原理
  • [存档]名词解释
  • [河北银行 2022 CTF]
  • [技术][.NET]一步一步学Linq to sql -- Joney Liu博客园整理
  • [蓝桥杯 2016 省 AB] 四平方和
  • [前缀和]Tokitsukaze and Strange Inequality Codeforces1678C