Unity DOTS 介绍和应用

官网: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:

    在这里插入图片描述

特性GetComponentTypeHandleSystemAPI.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 的等待批处理,还有系统的执行顺序,可能有不少时序问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值