关于 Unity DOTS
面向 Unity 6+ 开发者的 DOTS 技能,涵盖 ECS、Job System 和 Burst。它侧重现代 API,指导从 authoring、baking 到 system、query 和 job 的实现,并说明何时可能无需采用 DOTS。
主要功能
- 01Authoring 到 baking 的工作流
- 02现代 `ISystem` 与 `SystemAPI.Query` 模式
- 03使用 `IJobEntity` 并行处理实体
- 04Burst 与组件使用指南
- 05评估是否采用 DOTS
- 06故障排查与内存管理建议
适用场景
- 01在 Unity 6+ 构建 ECS 工作流
- 02将 GameObject 数据经 baking 转为实体
- 03实现实体并行处理
- 04排查 baking、query 或 Burst 问题
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ juliankerignard/ unity-skills --skill unity-dots安装后在 Claude Code 中输入/unity-dots确认已加载。
附带文件references/ecs-patterns.mdreferences/ecs-advanced.md
详细介绍
Unity DOTS — 面向数据的技术栈
此技能的作用
指导在 Unity 6+ 中实现 DOTS(实体组件系统 + 作业系统 + Burst 编译器)。涵盖高性能场景(数千个实体)的完整工作流:创作 -> 烘焙 -> 系统 -> 查询 -> 作业。重点介绍现代 API:ISystem、SystemAPI.Query、IJobEntity。不推荐使用已弃用的 API(Entities.ForEach、将 SystemBase 作为默认选项)。
前置条件
必需的软件包(通过 Package Manager 或 manifest.json 安装):
com.unity.entities(Unity 6 需 >= 1.3.x)com.unity.burst(>= 1.8.x)com.unity.collections(>= 2.4.x)
可选:
com.unity.entities.graphics— DOTS 渲染(Entities Graphics / Hybrid Renderer)com.unity.physics— DOTS 物理(取代实体的传统 PhysX)com.unity.transforms— 已包含在 entities 中,用于管理 LocalTransform
所需知识:具备 MonoBehaviour 基础知识,以便理解从创作到烘焙的转换。
快速开始
- 通过 Package Manager 安装 DOTS 软件包
- 创建一个 authoring MonoBehaviour 和一个 IComponentData(struct)
- 创建一个 Baker,将 authoring 转换为 entity
- 将 GameObject 放入 SubScene(烘焙的必要条件)
- 使用 SystemAPI.Query 创建一个 ISystem 来实现逻辑
- 在 system 和 jobs 上添加
[BurstCompile]
决策树
DOTS 并非总是必需的。采用之前请先评估:
Mon projet a-t-il besoin de DOTS ?
|
+-- Prototype / petit jeu (< 100 entites dynamiques) ?
| --> NON. MonoBehaviour est plus simple et suffisant
|
+-- Jeu moyen (100-1000 entites) ?
| --> PROBABLEMENT NON. Optimiser les MonoBehaviours d'abord
|
+-- Simulation massive (1000+ entites similaires) ?
| --> OUI. DOTS brille ici (foules, particules custom, voxels, RTS)
|
+-- Besoin de calcul CPU intensif (pathfinding, IA, physique custom) ?
| --> Job System + Burst SANS ECS. On peut utiliser les jobs seuls
|
+-- Migration d'un projet existant ?
| --> Hybride : garder MonoBehaviours + ajouter DOTS pour les systemes critiques
|
+-- Nouveau projet from scratch avec beaucoup d'entites ?
--> Full DOTS avec authoring/baking
ECS 路线图(Unity 6.4+)
- Unity 6.4:
com.unity.entities软件包将转为核心软件包(集成到编辑器中,无需再手动安装) - Unity 6.5(计划中):
Entity类型将发生结构性变化(改为 64 位 ID)。影响:自定义序列化以及在NativeContainer中存储Entity可能会受到影响。请提前做好准备,避免持久化原始Entity,改用业务标识符。
这些变化不会破坏 Unity 6.0-6.3 中的现有代码,但对长期架构决策很重要。
分步指南
Step 1:Component(仅数据)
// IComponentData = struct pure, pas de logique, juste des donnees
public struct MoveSpeed : IComponentData
{
public float Value;
}
public struct RotationSpeed : IComponentData
{
public float RadiansPerSecond;
}
规则:不得使用托管类型(string、class、List),不得包含复杂方法。一个 component = 实体的一个方面。
Step 2:Authoring + Baker
public class MoveSpeedAuthoring : MonoBehaviour
{
public float Speed = 5f;
}
public class MoveSpeedBaker : Baker<MoveSpeedAuthoring>
{
public override void Bake(MoveSpeedAuthoring authoring)
{
var entity = GetEntity(TransformUsageFlags.Dynamic);
AddComponent(entity, new MoveSpeed { Value = authoring.Speed });
}
}
Authoring MonoBehaviour 应添加到 SubScene 中的 GameObject 上。Baker 会在烘焙时将数据转换为 entity。
Step 3:System(逻辑)
[BurstCompile]
public partial struct MoveForwardSystem : ISystem
{
[BurstCompile]
public void OnUpdate(ref SystemState state)
{
float dt = SystemAPI.Time.DeltaTime;
foreach (var (transform, speed) in
SystemAPI.Query<RefRW<LocalTransform>, RefRO<MoveSpeed>>())
{
transform.ValueRW.Position +=
transform.ValueRO.Forward() * speed.ValueRO.Value * dt;
}
}
}
Step 4:并行 Job(可选,进一步提升性能)
[BurstCompile]
public partial struct MoveJob : IJobEntity
{
public float DeltaTime;
void Execute(ref LocalTransform transform, in MoveSpeed speed)
{
transform.Position += transform.Forward() * speed.Value * DeltaTime;
}
}
// Dans le system :
[BurstCompile]
public void OnUpdate(ref SystemState state)
{
new MoveJob { DeltaTime = SystemAPI.Time.DeltaTime }
.ScheduleParallel();
}
严格规则
始终:
- 使用
ISystem(struct)而非SystemBase(class)——兼容 Burst - 在 ISystem 和 jobs 上添加
[BurstCompile] - 使用
SystemAPI.Query(不要使用已弃用的Entities.ForEach) - 使用
RefRO<T>(读取)/RefRW<T>(写入)访问 components - 将 authoring GameObject 放入 SubScene
- 释放 NativeContainers(
Allocator.Temp除外) - 优先使用
IJobEntity对实体进行并行处理 - 优先使用可启用 component(
IEnableableComponent),而非动态添加或移除 component
绝不:
- 在 IComponentData 中使用托管类型(string、class、List、arrays)
- 在 job 中访问主线程(不得使用 Debug.Log 或传统 Unity API)
- 使用未 Dispose 的 NativeContainer(会造成内存泄漏)
- 使用
Entities.ForEach(Unity 6+ 中已弃用) - 将
SystemBase作为默认选项(除非需要托管类型)
故障排查
| 问题 | 解决方案 |
|---|---|
| "Burst compilation failed" | Burst 代码中使用了托管类型。使用 FixedString 替代 string,使用 NativeArray 替代 List |
| Entity 未创建 | 缺少 Baker,或 authoring 不在 SubScene 中 |
| System 未执行 | 检查 World。必要时添加 [UpdateInGroup(typeof(...))] |
| 性能没有提升 | 检查是否存在 [BurstCompile]。使用 Burst Inspector 分析性能 |
| NativeArray 泄漏警告 | 始终在 OnDestroy 中调用 Dispose(),或使用 Allocator.Temp |
| Query 返回 0 个结果 | 检查 Baker 中是否已正确添加 components |
| job 中出现 "InvalidOperationException" | 存在并发访问。使用 [NativeDisableParallelForRestriction] 或重新审视设计 |
| SubScene 未 bake | 重新导入 SubScene(右键 > Reimport)或重启编辑器 |
相关 Skills
/perf-audit— 评估 DOTS 是否适用于此用例/unity-code-gen— 生成 authoring/baker 样板代码/unity-animation— DOTS 动画(Entities Graphics animation)
参考资料
- 请参阅
references/ecs-patterns.md,了解基础模式(authoring、baking、queries、jobs) - 请参阅
references/ecs-advanced.md,了解高级模式(Burst、NativeContainers、混合模式、Aspects、DynamicBuffer) - Unity DOTS 官方文档
- Unity DOTS 示例
评论
支持 Markdown