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

UnityDots学习(四)

官方案例HelloCube和Tank学习研究:

HelloCube:

通用部分:

使用Authoring根据Inspector的勾选添加为Entity添加不同Component。然后每个System会根据实体添加的Component运行不同的System逻辑。

1. MainThread

简单构造System

先看System接口定义:

[RequireImplementors]public interface ISystem{/// <summary>/// Called when this system is created./// </summary>/// <remarks>/// Implement an `OnCreate` function to set up system resources when it is created.////// `OnCreate` is invoked before the the first time <see cref="ISystemStartStop.OnStartRunning(ref SystemState)"/>/// and <see cref="OnUpdate"/> are invoked./// </remarks>/// <param name="state">The <see cref="SystemState"/> backing this system instance</param>[RequiredMember]void OnCreate(ref SystemState state) { }/// <summary>/// Called when this system is destroyed./// </summary>/// <remarks>/// Systems are destroyed when the application shuts down, the World is destroyed, or you/// call <see cref="World.DestroySystem"/>. In the Unity Editor, system destruction occurs when you exit/// Play Mode and when scripts are reloaded./// </remarks>/// <param name="state">The <see cref="SystemState"/> backing this system instance</param>[RequiredMember]void OnDestroy(ref SystemState state) { }/// <summary>/// Implement `OnUpdate` to perform the major work of this system./// </summary>/// <remarks>/// <p>/// By default, the system invokes `OnUpdate` once every frame on the main thread./// To skip OnUpdate if all of the system's [EntityQueries] are empty, use the/// [RequireMatchingQueriesForUpdateAttribute]. To limit when OnUpdate is invoked, you can/// specify components that must exist, or queries that match specific Entities. To do/// this, call <see cref="SystemState.RequireForUpdate{T}"/> or/// <see cref="SystemState.RequireForUpdate(EntityQuery)"/>/// in the system's OnCreate method. For more information, see <see cref="SystemState.ShouldRunSystem"/>./// </p>/// <p>/// You can instantiate and schedule an <see cref="IJobChunk"/> instance; you can use the/// [C# Job System] or you can perform work on the main thread. If you call <see cref="EntityManager"/> methods/// that perform structural changes on the main thread, be sure to arrange the system order to minimize the/// performance impact of the resulting [sync points]./// </p>////// [sync points]: xref:concepts-structural-changes/// [C# Job System]: https://docs.unity3d.com/Manual/JobSystem.html/// [EntityQueries]: xref:Unity.Entities.EntityQuery/// [RequireMatchingQueriesForUpdateAttribute]: xref:Unity.Entities.RequireMatchingQueriesForUpdateAttribute/// </remarks>/// <param name="state">The <see cref="SystemState"/> backing this system instance</param>[RequiredMember]void OnUpdate(ref SystemState state) { }}

有3处接口

OnCreate里可以添加是否让System在OnUpdate里运行

类似:

当至少有一个Entity包含ExecuteIJobEntity组件。会激活Update

OnDestory就是在System被销毁时运行

OnUpdate里实现了简单的旋转。

这里Query是查询当前符合要求Component的实体。

RW是即可读又可写,RO是只可读,在system里不可改变其属性

2. IJobEntity

该案例是把System里执行的逻辑换成Job,这样程序的运行可以利用多核在不用非在主线程里运行。这样会提升CPU的使用率

这个Job实现的Schedule可以实现在代码里顺序执行。

比如增加下列代码测试,就可以发现物体上下移动了

3. Aspects

上述的读取数据还得根据情况写RW,RO。

Unity提供了一个接口如图:

不需要去传入值,且函数名可以自定义

在使用时直接查询就可以正确去找到对应拥有Component组件的实体进行遍历。这个比较方便

需要注意是必须用

readonly partial进行修饰。

可以看到Unity自己扩展定义后的内容

4. Prefabs

public partial struct SpawnSystem : ISystem{uint updateCounter;[BurstCompile]public void OnCreate(ref SystemState state){// This call makes the system not update unless at least one entity in the world exists that has the Spawner component.state.RequireForUpdate<Spawner>();state.RequireForUpdate<ExecutePrefabs>();}[BurstCompile]public void OnUpdate(ref SystemState state){// Create a query that matches all entities having a RotationSpeed component.// (The query is cached in source generation, so this does not incur a cost of recreating it every update.)var spinningCubesQuery = SystemAPI.QueryBuilder().WithAll<RotationSpeed>().Build();// Only spawn cubes when no cubes currently exist.if (spinningCubesQuery.IsEmpty){var prefab = SystemAPI.GetSingleton<Spawner>().Prefab;// Instantiating an entity creates copy entities with the same component types and values.var instances = state.EntityManager.Instantiate(prefab, 500, Allocator.Temp);// Unlike new Random(), CreateFromIndex() hashes the random seed// so that similar seeds don't produce similar results.var random = Random.CreateFromIndex(updateCounter++);foreach (var entity in instances){// Update the entity's LocalTransform component with the new position.var transform = SystemAPI.GetComponentRW<LocalTransform>(entity);transform.ValueRW.Position = (random.NextFloat3() - new float3(0.5f, 0, 0.5f)) * 20;}}}}
拿到对象实例,这里是Dots需要用结构体,所以跟Unity之前的GameObject生成有所区别
var prefab = SystemAPI.GetSingleton<Spawner>().Prefab;

这里是生成实例的DOTS版本

var instances = state.EntityManager.Instantiate(prefab, 500, Allocator.Temp);
public partial struct FallAndDestroySystem : ISystem{[BurstCompile]public void OnCreate(ref SystemState state){state.RequireForUpdate<ExecutePrefabs>();}[BurstCompile]public void OnUpdate(ref SystemState state){// rotationfloat deltaTime = SystemAPI.Time.DeltaTime;foreach (var (transform, speed) inSystemAPI.Query<RefRW<LocalTransform>, RefRO<RotationSpeed>>()){// ValueRW and ValueRO both return a ref to the actual component value.// The difference is that ValueRW does a safety check for read-write access while// ValueRO does a safety check for read-only access.transform.ValueRW = transform.ValueRO.RotateY(speed.ValueRO.RadiansPerSecond * deltaTime);}// An EntityCommandBuffer created from EntityCommandBufferSystem.Singleton will be// played back and disposed by the EntityCommandBufferSystem when it next updates.var ecbSingleton = SystemAPI.GetSingleton<BeginSimulationEntityCommandBufferSystem.Singleton>();var ecb = ecbSingleton.CreateCommandBuffer(state.WorldUnmanaged);// Downward vectorvar movement = new float3(0, -SystemAPI.Time.DeltaTime * 5f, 0);// WithAll() includes RotationSpeed in the query, but// the RotationSpeed component values will not be accessed.// WithEntityAccess() includes the Entity ID as the last element of the tuple.foreach (var (transform, entity) inSystemAPI.Query<RefRW<LocalTransform>>().WithAll<RotationSpeed>().WithEntityAccess()){transform.ValueRW.Position += movement;if (transform.ValueRO.Position.y < 0){// Making a structural change would invalidate the query we are iterating through,// so instead we record a command to destroy the entity later.ecb.DestroyEntity(entity);}}}}

Dots版本的删除实体:

var ecbSingleton = SystemAPI.GetSingleton<BeginSimulationEntityCommandBufferSystem.Singleton>();
var ecb = ecbSingleton.CreateCommandBuffer(state.WorldUnmanaged);
ecb.DestroyEntity(entity);

BeginSimulationEntityCommandBufferSystem.Singleton:我的理解就是全部关闭实例Manager
EntityCommandBuffer:是每个实体管理的控制器,类似GameObjectManager。所有的创建销毁实体都是通过他来控制。
http://www.xdnf.cn/news/1128.html

相关文章:

  • 关于RPC
  • 图数据库nebula测试指南
  • 在 NVIDIA Orin (JetPack 6.0) 上安装 PyTorch 2.4 + Torchvision 0.19
  • 每日算法-250422
  • 几种Word转换PDF的常用方法
  • 如何在idea里创建注释模版
  • 真我推出首款 AI 翻译耳机,支持 32 种语言翻译
  • 拥抱健康生活,开启养生之旅
  • Android Jetpack Compose基础实践
  • iscsi服务端安装及配置
  • 【Python爬虫基础篇】--3.cookie和session
  • Office文档图片批量提取工具
  • 异构网络环境下的切换策略研究
  • 边缘计算全透视:架构、应用与未来图景
  • 基于Java+MySQL实现(Web)企业仓库存储管理系统
  • 金融数据分析(Python)个人学习笔记(12):网络爬虫
  • 【产品经理从0到1】用户研究和需求分析
  • 从项目真实场景中理解二分算法的细节(附图解和模板)
  • nodejs使用require导入npm包,开发依赖和生产依赖 ,全局安装
  • 【HTML】【Web开发】滑动条挑战
  • 使用 Spring Boot Admin 通过图形界面查看应用配置信息的完整配置详解,包含代码示例和注释,最后以表格总结关键配置
  • Embedding与向量数据库__0422
  • 实验一-密码学数学基础
  • ​SYSTEM WAKE-UP(系统唤醒)​和外部中断唤醒(EXTI唤醒)
  • 建筑末端配电回路用电安全解决方案
  • 【数据结构 · 初阶】- 堆的实现
  • 抱佛脚之学SSM四
  • Redis—为何持久化使用子进程
  • 【Hive入门】Hive架构与组件深度解析:从核心组件到生态协同
  • Go语言中 defer 使用场景及深度注意事项指南