Unity DOTS Entities1.0.0-pre.15文档翻译(随缘更新中...)

官方文档Entities overview | Entities | 1.0.0-pre.15 (unity3d.com)

一、Entities 总览

Entities包,是Unity“面向数据的技术堆栈(DOTS)”的一部分, 实现了一套面向数据的“实体-组件-系统(ECS)”架构。

请参阅GitHub - Unity-Technologies/EntityComponentSystemSamples以获取一些介绍材料,包含教程,实例和视频。

已知问题

  1. 运行时在一个system的静态方法中调用SystemAPI的方法会产生报错:No suitable code replacement generated, this is either due to generators failing, or lack of support in your current context.

  1. Blob Assets不支持带有yield return的方法。

升版本引导

从Entities0.51升级到1.0,你需要做的如下:

  1. 更新Transforms

  1. 更新conversions

  1. 移除GenerateAuthorComponent

  1. 更新get和create一个system的代码

  1. 移除继承ISystem的系统里的Entities.Foreach

  1. 更新IJobChunk来处理可激活的组件

  1. IJobEntityBatch和IJobEntityBatchWithIndex换成IJobChunk

  1. 重命名异步EntityQuery的get/set方法

  1. IJobEntityBatch和IJobEntityBatchWithIndex换成IJobChunk

  1. 刷新系统状态组件,清理组件

  1. 刷新TypeManager代码,使用TypeIndex而非int

  1. 刷新被直接访问的EntityCommandBufferComponent

  1. 更改system update的代码

  1. 重命名EntityQueryDescBuilder

  1. 更新SystemBase.Time和SystemState.Time

  1. 添加Entities Graphics包到项目里

移除的:

自动生成光照模式移除了

Entities1.0的新特性

新增:

  1. Aspects

  1. Baking

  1. Enableable components

  1. The Journaling editor window

  1. New authoring-tuntime workflow

  1. Query<T>

更新:

  1. Tansforms

  1. 无需BuildConfiguration

  1. 设置从DOTS menu菜单挪到Preference窗口

版本日志:Changelog | Entities | 1.0.0-pre.15 (unity3d.com)

二、开始

安装

Entites1.0要求Unity版本2022.2.0b8及以上。

打开Package Manager窗口(Window->Package Manager),

点击左上角+号Add the package by its name,

安装com.unity.entities和com.unity.entities.graphics。

编辑器使用Visual Studio2022+或Rider2021.3.3+,以支持Source Generators | Microsoft Learn

要在Entities项目中获得最佳性能,请禁用Unity的Domain Reload:

在Edit->Project Setting->Editor菜单中,

启用Enter Play Mode Options,

禁用Reload Domain和Reload Scene.

注意:如果你禁用了Domain Reloads,要留意静态属性和事件的使用。

ECS包内容

Unity的ECS由一系列包,和部分参与协作的Unity引擎内容构成,来帮助你创建高效的代码。

主要有:

  1. Entities(本包):ECS的实现。

  1. C# Job System:快速,安全,多线程的代码解决方案。

  1. Burst compiler:可以深度优化代码的编译器。

  1. Collections:一套非托管类型的集合,例如lists和hash maps。这些在2和3中会用到,因为这些上下文只能访问非托管数据。

  1. Mathematics:专为3优化过的数学库。

基于这些核心模块,还有一些DOTS包:

  1. Physics:无状态的和确定性的物理系统。

  1. Netcode:客户端-服务器网络编码解决方案。

  1. Entities Graphics:使用可编程渲染管线(SRP)来渲染entities。

理解ECS工作流

探索Unity ECS工作流,来理解在Unity中,各个模块如何通过协作,以实现面向数据的编程。

使用Unity ECS框架创建Unity应用的工作流,从原理上和实现上,都不同与以往的面向对象的Unity应用。在你开始使用这套框架创建项目之前,理解ECS工作流是有必要的。

  1. 创建subscene

ECS使用 subscenes来存放你的应用内容。添加GameObject和MonoBehaviour组件到subscene,bakers会将其转换成entities和ECS组件。

  1. 创建ECS components

Components为你的应用存储数据。 systems通过读写ECS Component的数据,来为你的应用创建行为。ECS工作流是面向数据的,所以在编写systems或创建entities之前,规划数据格式并创建好ECS Component是更好的。

components有很多类型,用于不同的功能。了解更多信息,参考Component types.

  1. 创建entities

Entities代表着应用中的不同事物。添加GameObjects到subscene,以在编辑器下创建entities。baking过程会把这些GameObejcts转换成entities。另外,在转换出的entities上添加ECS Components,你也可以创建bakers。当你创建baker时,要定义它是哪个Mono组件的,然后编码使用这个Mono的数据来创建并添加ECS component到转换出的entities上。你也可以从baker创建额外的entities,并添加ECS component。在这个流程中,Mono组件也称作authoring component。

TIP:建议你创建的authoring components类名都以Authoring结尾。

  1. 创建systems

Systems 为你的应用定义行为。为此它们可以查询和转换Component的数据,创建或销毁entities,添加或移除entities上的components。默认情况下,Unity会将其你创建的system实例化并添加到默认的 world

systems有很多类型,用于不同的功能。了解更多信息,参考System types.

  1. 优化systems

默认情况下,system中的代码是在主线程中同步执行的。如果系统调集了很多entities并能获益于多线程,推荐创建Burst compatible jobs,尽可能使其并行。Burst将C#代码优化编译,并支持多线程。

如果一个system比较简单,例如只是处理少量的entities的数据,并行调度jobs的消耗可能会高于多线程带来的优化。分析这种jobs,用CPU profiler对比Unity在使用和不使用多线程时的耗时。如果调度jobs使代码多线程运行使得Unity耗时更长,尝试如下方法优化job:

  1. 在主线程中运行job。

  1. 如果system时非托管的ISystem,用SystemAPI.Query和一般的foreach替代job。然后你可以应给包含SystemAPI.Query的方法加上BurestCompile标签,来让query和代码被Burst编译。

Spawner示例

【Mono(Authoring)通过Baker转成Componnet】

using UnityEngine;

using Unity.Entities;

using Unity.Mathematics;

public class SpawnerAuthoring : MonoBehaviour

{

public GameObject Prefab;

public float SpawnRate;

}

public struct Spawner : IComponentData

{

public Entity Prefab;

public float3 SpawnPosition;

public float NextSpawnTime;

public float SpawnRate;

}

public class SpawnerBaker : Baker<SpawnerAuthoring>

{

public override void Bake(SpawnerAuthoring authoring)

{

AddComponent(new Spawner

{

Prefab = GetEntity(authoring.Prefab),

SpawnPosition = authoring.transform.position,

NextSpawnTime = 0.0f,

SpawnRate = authoring.SpawnRate

});

}

}

【System】

using Unity.Entities;

using Unity.Transforms;

using Unity.Burst;

[BurstCompile]

public partial struct SpawnerSystem : ISystem

{

public void OnCreate(ref SystemState state) { }

public void OnDestroy(ref SystemState state) { }

[BurstCompile]

public void OnUpdate(ref SystemState state)

{

foreach (RefRW<Spawner> spawner in SystemAPI.Query<RefRW<Spawner>>())

{

if (spawner.ValueRO.NextSpawnTime < SystemAPI.Time.ElapsedTime)

{

Entity newEntity = state.EntityManager.Instantiate(spawner.ValueRO.Prefab);

state.EntityManager.SetComponentData(newEntity, LocalTransform.FromPosition(spawner.ValueRO.SpawnPosition));

spawner.ValueRW.NextSpawnTime = (float)SystemAPI.Time.ElapsedTime + spawner.ValueRO.SpawnRate;

}

}

}

}

【多线程System】

using Unity.Entities;

using Unity.Transforms;

using Unity.Burst;

[BurstCompile]

public partial struct SpawnerSystem : ISystem

{

public void OnCreate(ref SystemState state) { }

public void OnDestroy(ref SystemState state) { }

[BurstCompile]

public void OnUpdate(ref SystemState state)

{

new ProcessSpawnerJob

{

ElapsedTime = SystemAPI.Time.ElapsedTime,

Ecb = SystemAPI.GetSingleton<BeginSimulationEntityCommandBufferSystem.Singleton>().CreateCommandBuffer(state.WorldUnmanaged).AsParallelWriter()

}.ScheduleParallel();

}

}

[BurstCompile]

public partial struct ProcessSpawnerJob : IJobEntity

{

public double ElapsedTime;

public EntityCommandBuffer.ParallelWriter Ecb;

private void Execute([ChunkIndexInQuery] int chunkIndex, ref Spawner spawner)

{

if (spawner.NextSpawnTime < ElapsedTime)

Entity newEntity = Ecb.Instantiate(chunkIndex, spawner.Prefab);

Ecb.SetComponent(chunkIndex, newEntity, LocalTransform.FromPosition(spawner.SpawnPosition));

spawner.NextSpawnTime = (float)ElapsedTime + spawner.SpawnRate;

}

}

}

三、相关概念

Entities包使用ECS架构组织代码和数据。entity是一个特殊字符,如同一个GameObject轻量的非托管替代。entity与其ID相关的component协同工作。与GameObject不同,entities不包含代码:他们是system处理数据的单元。

  1. Entity概念

  1. Component概念

  1. System概念

  1. World概念

  1. Archetype概念

  1. Structural changes概念

  1. Aspect概念

四、Component概述

Component表示ECS架构的数据。Entities与Compnents协作,systems提供读写component数据的逻辑。本节将介绍ECS Components,并解释如何使用它们。

  1. Component 类型

  1. 向entity添加components

  1. 从entity移除components

  1. 读写component数据

  1. 支持的本地数据容器

五、System概述

  1. systems介绍

  1. 使用systems

  1. 遍历component数据

  1. 查询entity和数据

  1. 查找任意数据

  1. 时间

六、使用jobs调度数据

  1. Job拓展

  1. 常规Job

  1. 使用Job.WithCode调度后台jobs

  1. Job依赖

七、转换数据

你项目里的数据通过Baking转化成entities和components。本节讲解Unity如何转换你的数据。

1.通过Baking转换数据

Baking提供一个系统,在Editor下转换GameObejct数据,在Runtime时写入EntitiyScene。

Baking可分解为多个部分,但核心是关键的两步:Bakers和Baking Systems。

当你打开一个SubScene并在其中编辑authoring物体时,Baking也会执行。

ECS会检测你正在进行的修改,并计算出完成这些变换所需Bakers的最小量。

这个结果在编辑或运行时会传递到Entity World。

2.Subscenes

3.流式scenes

八、脚本

  1. Transforms

  1. Blob assets

  1. Prebuilt custom allocators

九、编辑器

  1. 偏好设置

  1. 窗口

  1. 属性面板

十、资源管理

十一、性能与调试

  1. Profiler模块

  1. Journaling

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值