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

Entities - 遍历与查询

DOTS 程序的三大主要工作:

  • 设计与组织数据
  • 遍历与查找数据
  • 修改与更新数据

在【Component 类型】中说过可以将 Component 按照数据访问类型进行划分,分别是 Entity,Chunk,Element,数据与查询中也是如此

1、遍历查询 Entity 数据的 5 种方式

  • SystemAPI.Query + ForEach

SystemAPI.Query 用于在合集中过滤出我们需要的子集,然后通过 ForEach 遍历,Query中可以有七种重载查询类型:

但是Query 有两个使用限制:

(1)DynamicBuffer 只读限制:默认为读写访问,如果希望只读,必须自己实现

(2)不能存储 SystemAPI.Query<T>(),然后在一个或多个 foreach 语句中使用它(这是因为SytemAPI.Query 的模板类型是要在编译时确定并生成代码的,也就是说不能用分支语句去控制 SystemAPI.Query 语句的查询结果)

(3)只能在主线程运行

  • IJobEntity

这是一种隐式查询后遍历的一种方式

(1)与Entities.ForEach功能类似,为每个Entity调用一次Execute
(2)可在多个System中重用
(3)底层是IJobChunk实现的
(4)查询方式WithAll、WithAny、WithNone、WithChangeFilter、WithOptions
(5)可以通过 【EntityIndexInQuery】 属性来在 Execute 方法中获取 Entity 遍历查询中的索引

[BurstCompile]
public partial struct CopyPostion : IJobEntity
{public NativeArray<float3> copyPositions;public void Execute([EntityIndexInQuery] int entityIndexInQuery, in LocalTransform localTransform){copyPositions[entityIndexInQuery] = localTransform.Position;}
}
  •  IJobChunk

(1)遍历ArcheType Chunk
(2)为每个Chunk调用一次Execute
(3)一般用在不需要遍历每个Chunk中Entity的情况或者对Chunk内的Entity执行多次遍历或以不寻常顺序遍历的情况
(4)useEnabledMask与ChunkEnableMask来辅助过滤Enableable Component未激活的Entity

注意第(4)点,IJobEntity 和 Entities.ForEach 遍历时会自动跳过与其 EnableableComponent 状态不匹配的 Entity,但是 IJobChunk 不会

  • Entities.ForEach

(1)只用于继承SystemBase创建的System

(2)定义是一个Lambda表达式

(3)有太多的使用限制

  • Manually

(1)entityManager.GetAllEntities()

(2)entityManager.GetAllChunks()

再通过 Foreach 方法去遍历上面两个接口得到的合集,设置限制条件查询。这种方法使用限制最小,但从性能角度来说是不划算的

举个例子:

以【Entity的创建模式】中的旋转方块的例子为基础,这次设置三种不同颜色的方块,并且每个颜色的方块写一个旋转 System,可以发现方块旋转的非常快,通过 Systems 可以看到,每个 System 处理的 Entity 数量都是 9 个,相当于每个 System 都在对每个颜色的方块进行旋转,每一帧进行了三次旋转处理。

这个时候为了区分每个颜色的方块,就可以用 Tag Component 来分类每个颜色的方块,Tag Component 不包含数据,可以在 Archetype 窗口中看到这些 Component 占了 0 字节,以其中一个为例:

struct RedCubeTag:IComponentData
{
}
public class RedCubeTagAuthoring : MonoBehaviour
{public class Baker:Baker<RedCubeTagAuthoring>{public override void Bake(RedCubeTagAuthoring authoring){var redCube =new RedCubeTag();AddComponent(redCube);}}
}

然后更新 System 中的 Update

[BurstCompile]
public void OnUpdate(ref SystemState state)
{float deltaTime = SystemAPI.Time.DeltaTime;foreach (var (transform, speed, tag)) in SystemAPI.Query<RefRW<LocalTransform>, RefRO<RotateSpeedComponent>, RefRO<RedCubeTag>>()){transform.ValueRW = transform.ValueRO.RotateY(speed.ValueRO.rotateSpeed * deltaTime);}
}

还有一种情况,如果要查询所有 Component A 与 C 的 chunk

那么通过 SystemAPI.Query<A,C>(),包含 A,B,C的 chunk 也会被获取,如果要获取只包含 A,C组件的 chunk,那么可以通过创建自定义的 query,并且可以通过多线程处理

new EntityQueryBuilder(Allocator.Temp) .WithAll<A>0 .WithAll<C>() .WithNone<B>() .Build(this).

http://www.dtcms.com/a/394578.html

相关文章:

  • TargetGroup 全面优化:从六个维度打造卓越用户体验
  • Proxy与Reflect
  • 浅解Letterbox算法
  • 【Triton 教程】triton_language.permute
  • JavaScript洗牌算法实践
  • 掌握timedatectl命令:Ubuntu 系统时间管理指南
  • 【RT Thread】RTT内核对象机制详解
  • Seata分布式事务
  • 用例图讲解
  • makefile原理
  • AUTOSAR CP开发流程总结
  • 通过VNC实现树莓派远程桌面访问
  • linux信号done
  • BeanUtils.copyProperties 映射规则详解
  • 物联网 frid卡控制
  • LeetCode刷题记录----322.零钱兑换(Medium)
  • 2015/07 JLPT听力原文 问题四
  • Redis集群实验
  • 昇腾生态双支柱:MindSpore 与 CANN 的全栈技术解析
  • YOLO系列——实时屏幕检测
  • 牛客算法基础noob49 上三角矩阵判定
  • autosar 中OS模块理解
  • 通俗范畴论17.2 向量空间的对偶与双对偶
  • huggingface_hub 安装部署问题汇总
  • 在我的Java项目中为什么使用AllArgsConstructor注解注入的方式启动报错了:
  • π0:一个 VLA 流匹配模型用于通用机器人控制(又称 pi0)
  • Information theorem-Entropy
  • 编译原理实验报告——词法分析程序
  • 整体设计 完整的逻辑链条 之4 认知逻辑视角 —— 前序驱动的认知演进体系 之2
  • C/C++正则表达式PCRE2库