官网:https://unity.com/cn/dots

手册:https://docs.unity3d.com/Packages/com.unity.entities@1.3/manual/index.html

样例:https://github.com/Unity-Technologies/EntityComponentSystemSamples

ECS Physics 手册:https://docs.unity3d.com/Packages/com.unity.physics@1.3/manual/index.html

ECS Physcis 工作流:https://learn.unity.com/tutorial/ecs-physics-havok-physics-for-unity-and-unity-physics#63089698edbc2a43aba17b9c

软浮点确定性物理:https://www.reddit.com/r/Unity3D/comments/lkxb9d/crossplatform_deterministic_physics_with_unity/

DOTS 最佳实践:https://learn.unity.com/course/dots-best-practices

最新样例(2024.07):https://github.com/Unity-Technologies/ECSGalaxySample

前言

在这里插入图片描述

  • 截至目前(2024年9月),Unity Entity出到1.3+版本,ChatGPT的知识库最新是2023年10月,对应Unity Entities包是1.0+版本,有些差异,但大部分问题还是能教。

子场景

  • 因为原来Unity场景不支持ECS组件,所以单独弄了个“子场景”来烘培ECS组件。

  • 子场景也可以用来多人协作,比如美术做地编避免冲突。

在这里插入图片描述


实体和组件烘培

  • 用来将传统MonoBehaviour组件转换成ECS中的Component,需要自己写具体转成代码。根据需要可以生成生成多个Component。

在这里插入图片描述

  • Unity DOTS Physics 也支持以组件形式挂在预制体上,创建时烘培。

在这里插入图片描述

  • 一些传统MonoBehaviour也可以有兼容自动转成Component组件,比如SpriteRenderer。
    在这里插入图片描述
    在这里插入图片描述

系统

  • https://docs.unity3d.com/Packages/com.unity.entities@1.3/manual/systems-comparison.html#differences-between-systems

  • 继承实现主要分两种,ISystem接口和SystemBase类。

    • ISystem:纯ECS代码,不需要被外部调用这个系统时,用这种。性能比`SystemBase`好。

    • SystemBase:需要被外部系统调用,或者跑一些传统托管代码,用这种。

在这里插入图片描述

系统执行顺序

  • https://docs.unity3d.com/Packages/com.unity.entities@1.3/manual/systems-update-order.html#default-system-groups

  • 默认不指定顺序时,是在MonoBehaivor的Update后执行。总体分三组:

在这里插入图片描述

  • 菜单打开 Windows/Entities/Systems,可以查看当前系统执行顺序。
    在这里插入图片描述

遍历处理实体

  • https://docs.unity3d.com/Packages/com.unity.entities@1.3/manual/systems-iterating-data-intro.html

  • 效率:IJobChunk>IJobEntity>SystemAPI.Query>Entities.ForEach

  • 编写难度:IJobChunk>IJobEntity>Entities.ForEach>SystemAPI.Query

  • IJobChunk:需要属性ECS底层直接操作Chunk代码,要求较高。

  • SystemAPI.Query:效率比IJobEntity差一点点,写得方便,建议只在简单操作时用。

  • 推荐首选IJobEntity
    在这里插入图片描述

  • Entities.ForEach:如果要操作一些unity还未支持的托管代码,要求必须在主线程执行时,比如要修改SpriteRender.sprite:

    在这里插入图片描述

特性 GetComponentTypeHandle SystemAPI.GetComponentLookup
数据处理范围 适合批量、块(Chunk)级别处理。 更适合单个实体的按需查询。
性能优化 通过缓存 ComponentTypeHandle 提供更高效的批量处理。 每次查询生成新的 ComponentLookup,单独查询实体时可能开销较大。
常见使用场景 需要处理大量实体,常用于 IJobChunkEntities.ForEach 等场景。 按需访问特定实体的组件,更灵活但不适合大量实体查询。
线程安全 适用于并行作业(如 IJobChunk),可以安全并行处理多个实体。 主要用于主线程上下文,适合单线程或少量实体查询。
缓存机制 可以每帧缓存一次 ComponentTypeHandle,减少不必要的查询。 每次使用 GetComponentLookup 时都创建新的访问器,无法缓存。
块级别处理 能够高效处理整个 ArchetypeChunk,块级优化较好。 逐实体查询,没有按块的优化。

增删改实体组件

  • https://docs.unity3d.com/Packages/com.unity.entities@1.3/manual/iterating-entities-foreach-ecb.html

  • EntityCommandBuffer :创建删除实体、添加删除组件,修改组件等修改实体指令,指令队列,是延迟的异步执行,统一执行,线程安全。缺点也是因为异步,有需要立即生效就不要用。

    • 如果添加的对应在对应命令系统之后,会等到下一帧这个系统时候再执行。

    在这里插入图片描述


调试

  • ECS的代码相比传统代码编译更复杂一点,要断点调试时,需要生成额外的代码,有时候断点不上时,可以尝试重启Unity,编辑器先附加Unity再启动游戏。

  • ECS提供一些菜单工具,方便查看ECS系统相关内容。
    在这里插入图片描述

Hierarchy

  • 专门看Entity的层级面板

在这里插入图片描述

Components

  • 查看当前定义了哪些Components和其依赖。
    在这里插入图片描述

Systems

  • 查看当前所有ECS的系统

在这里插入图片描述

Archetypes

  • 原型:https://docs.unity3d.com/Packages/com.unity.entities@1.3/manual/concepts-archetypes.html

  • 有相同种类组件的算一种原型,同一种原型查询处理更快,频繁增删导致原型变化(产生同步点)影响性能。
    在这里插入图片描述

在这里插入图片描述

Journaling

  • 日志:https://docs.unity3d.com/Packages/com.unity.entities@1.3/manual/entities-journaling.html

  • 比如要查一个实体表现异常了,通过搜索过滤可以查到这段时间内的所有组件操作。

  • 也有API可以在调试时用Watching查指定Job的操作记录,见上面链接。
    在这里插入图片描述


Profiler

  • CPU:除了在主线程可以看System中Update的主线程耗时,也可以看Job在子线程中耗时
    在这里插入图片描述

  • EntitiesMemory:查看每个Archetype原型总的内存分配占用

  • EntitiesStructuralChange:每个实体变化产生开销
    在这里插入图片描述


实际应用

  • 碰撞触发计算:500+个实体,原来使用[Box2D]改造耗时90ms,用DOTS后主线程耗时2ms。
    在这里插入图片描述

  • 怪物避免堆叠的集群移动:300+实体,优化前后37ms->7ms,优化不完全,7ms里还有6ms其实是回调旧系统重新同步坐标,因为还未把实体完全移植到DOTS中。
    在这里插入图片描述

  • 经验豆掉落道具,这种只有sprite的对象,去掉了GameObject,只用Entity来绘制Sprite,但因为DOTS没有计划支持SpriteRender,所以还是用SpriteRenderer在主线程设置,会有较高耗时(0.6ms)。后续可以考虑使用Entities.Graphics代替,或者用Graphics.DrawMeshInstance来处理。

在这里插入图片描述


真机兼容性

  • Entities 1.3.5 兼容HybridCLR压缩包:

    • https://download.csdn.net/download/l773575310/90373769
  • HybridCLR 免费版目前最新仅支持Entity1.0.16(上面1.3.5是自己对比升级,可以用),需要替换package,否则真机无法使用DOTS。

    • https://hybridclr.doc.code-philosophy.com/docs/basic/dots

    • 经测试,在顶层Assembly-CSharp.dll加的dots代码,打包有报错,还未查到具体原因。(最小测试Demo正常,没用热更整个程序集)
      在这里插入图片描述

    • 测试dots代码单独封装dll,加载热更正常。

  • demo测试工程如下
    https://download.csdn.net/download/l773575310/90373786

  • 未解决的问题:游戏demo工程命令行打包出现不该出现的调试断言宏生效情况,再次手动打包后正常。是HybridCLR加的,catch异常,测试正常

    在这里插入图片描述

右边是命令行打包,在ecs的TypeManagerSystem注册系统类型出现了个应该编辑器用的

在这里插入图片描述

[Conditional(“UNITY_ASSERTIONS”)] 真机不应该生效,导致异常中断,这个方法是HybridCLR加的


注意事项

  • 不要在Job中删除容器数据,并发情况下容易出问题。

  • 因为job执行异步,EntityCommandBuffer 的等待批处理,还有系统的执行顺序,可能有不少时序问题。

Logo

火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。

更多推荐