mcpField
U
Unity DOTS

Unity DOTS

github.com/juliankerignard开发850 次安装33 周前更新
代码仓库

关于 Unity DOTS

面向 Unity 6+ 开发者的 DOTS 技能,涵盖 ECS、Job System 和 Burst。它侧重现代 API,指导从 authoring、baking 到 system、query 和 job 的实现,并说明何时可能无需采用 DOTS。

主要功能

  1. 01Authoring 到 baking 的工作流
  2. 02现代 `ISystem` 与 `SystemAPI.Query` 模式
  3. 03使用 `IJobEntity` 并行处理实体
  4. 04Burst 与组件使用指南
  5. 05评估是否采用 DOTS
  6. 06故障排查与内存管理建议

适用场景

  1. 01在 Unity 6+ 构建 ECS 工作流
  2. 02将 GameObject 数据经 baking 转为实体
  3. 03实现实体并行处理
  4. 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 基础知识,以便理解从创作到烘焙的转换。

快速开始

  1. 通过 Package Manager 安装 DOTS 软件包
  2. 创建一个 authoring MonoBehaviour 和一个 IComponentData(struct)
  3. 创建一个 Baker,将 authoring 转换为 entity
  4. 将 GameObject 放入 SubScene(烘焙的必要条件)
  5. 使用 SystemAPI.Query 创建一个 ISystem 来实现逻辑
  6. 在 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