Unity DOTS Baking与Baker详解

Unity DOTS Baking与Baker详解

  最近DOTS终于发布了正式的版本, 我们来分享一下DOTS里面Baking 与Baker的关键概念,方便大家上手学习掌握Unity DOTS开发。

  Unity DOTS开发模式,为了让大家在”创作”游戏的时候使用原来组件方式来编辑游戏场景与资源,同时Unity提供了一种Baking机制,把普通的GameObject数据转成ecs模式下的entity数据,程序运行的时候,直接加载转换好的ECS模式的数据。在深入了解Baking与Baker机制之前,我们先熟悉几个概念:

  • Authoring: 英文单词是”创作”的意思,上文提到ECS模式开发的时候创作游戏节点可以使用原来的方式,再通过baking转换。所以那些待转换成ecs 模式的GameObject与Component被称为Aurthoring。
  • Authoring Scene: 要转换的传统的GameObject与组件所在的场景称为Authoring Scene。
  • Authoring Component: 待转换的传统模式下的组件。
  • Authoring GameObject: 待转换的传统模式下的GameObject。
  • Baking: 指的是把传统GameObject+组件数据转成ecs模式下所需要的数据的过程。
  • Baker: 指的是某种Authoring转ECS模式的具体执行者与执行逻辑。

  有了这些概念以后,接下来我们来详细地分析Unity DOTS的Baking与Baker。

Unity DOTS Baking 机制核心剖析

  Baking是一个单向不可逆的过程,主要是负责把传统的GameObject+Component数据转换成ECS模式下的Entity+Component数据。在DOTS开发模式下,数据可以分成两种,一种是创作数据Authoring data,一种是运行时的ECS模式的数据runtime data。Authoring data灵活,直观,方便我们的创作(即以前的创作模式),ecs模式下的运行数据runtime data,高效,运行时能快速地生成entity数据。Baking这个过程是发生在编辑模式下,在游戏运行之前就完成了Baking转换,游戏中直接使用bake好的数据即可。如果在游戏中做Baking转换,那么会消耗游戏的运行性能。

  • Authoring Data: 当你在编辑你的游戏项目应用的时候,像传统的脚本,资源,以及其它的一些游戏数据的依赖,这种编辑方式非常灵活,方便用户查看,与使用。这些编辑的数据,我们叫做Authoring data。
  • Runtime Data 是ECS模式运行的时候需要的数据,当你运行程序时,作为游戏数据来进行处理。这种模式的数据有高效的性能与高效的存储。它是为计算机运行处理而设计,换句话说对开发者的直观性,没有传统的GameObject模式那么友好。

  开发者需要在Unity里面把Authoring Scene作为SubScene加载进来,当编辑Authoring场景中的Authoring 物体时,Baking过程会被触发,并在后台完成。

  Baking有两种模式:

  • Full Baking(全局Baking): 对Authoring Scene里面的所有物体做Baking操作。
  • Incremental Baking(增量Baking): 只对变化了的物体进行Baking操作。

  当整个Authoring Scene被导入的时候,会触发Full Baking。FullBaking是在编辑器的后台模式下处理的,运行的时候不带任何的GUI界面。当一个场景需要被Baking的时候,编辑器就在后台启动执行Baking。Baking是异步操作的,Baking的时候不影响你正常的Unity的操作。但是第一次打开场景的时候可能需要等几秒钟,等场景Bake好后,后面再使用就会快很多。Full baking 只会发生在 ECS data需要加载的时候,不会发生在创作与编辑 GameObject的数据的时候。以下一些情况会导致Full Baking:

  1. 烘培好的ECS模型下的 entity场景数据不在磁盘上,就会发生Full Baking。
  2. Authoring Scene的内容被修改,同时烘焙好的entity scene数据(Runtime Data)过期。
  3. 如果baking code 在编译Baker代码后发现包含了一个 [BakingVersion] 的attribute (特性), 这个意味着 bake代码被改变了,entity scene 过期了,就会引发full baking。
  4. Baking code 的 [BakingVersion] 的属性被修改了,会导致full baking。
  5. Project Setting里面的关于Entities 的设置有改变,会导致full baking。
  6. 在inspterctor 检查器中,点击了 "ReImport"重新导入subscene, 会导致full baking。
  7. 你在编辑器的 Preferences (偏好设置)清理了baking cache,会到导致full baking。Full Baking会输出一些文件到存储到硬盘上,当编辑器运行程序会加载这些文件。

  当使用subscene机制, 加载一个"创作场景"的时候,同时也初始化了 incremental baking。当在场景中执行一个incremental baking 的过程时,意味着当你编辑一个 "创作创景"的时候,可以直接访问和使用你的baking的结果。它只针对变化的数据与组件进行Bake。

Unity DOTS Baker 机制核心剖析

  本身Baking这个过程也是基于ECS模式的,一个简单的 Baking system(baking算法) 需要一个 Baker 从场景中读取里面的"authoring data",并把数据生成到entity 的组件中。创建一个Baker, 新建一个类 Baker, 模板的参数类型就是要转换authoring components的类型。 "authoring components" 创作时候的组件一般都是用的Unity的Comoponent, 通常情况下就是MonoBehaviour。一个Baker定义了一个Bake的函数方法,这个方法把要转的authoring component 作为参数输入到函数。Baker函数通过参数获取authoring component 的数据,从而转成entity component数据。如果Unity 执行一个full baking, 它会把authoring scene 所有的 "authoring components"全部baker执行一次,完成数据转换。增量更新,只会 bake 那些自己或依赖被修改的 authoring组件, 只有这些组件的Baker才会被调用。

  每个组件数据的Baker还需要向系统来注册它执行时候的依赖关系,这样当它依赖的数据发生变化的时候,才会触发这个组件的Baker调用。默认情况下一个Baker只能访问一个 authoring component,但是有时候仍然需要从其它的组件, GameObjects 或者各种各样的资源, 所以整个baking 处理需要知道这些依赖关系,如果其它的这些对象改变了,那么这个baker也需要重新执行。例如,如果是一个 authoring GameObject 是一个cube, Unity在bake的时候,就会把这个entity 渲染成一个cube,如果这个authoring GameObject 随后被修改成了一个 球体, 那么 ECS也必须要相通地做出改变,要把这个entity渲染成球体,这个就意味着unity要删除以前早期的Cube Entity, 并创建一个新的球的entity,或者改变entity让他显示一个球体。又比如 一个GameObject 有一个材质, 依赖一个 scriptable object。Baker需要定义一个资源依赖,这样才能确保资源 scriptable object被改变的时候,这个object 会被重新Baker。整个过程全部都是自动发生的,我们普通开发者可以不用管。

  最后给大家展示一个普通MonoBehaviour Component的Baker,代码如下:

ECS Component:
publicstructDependentData:IComponentData
{
    publicfloatDistance;
    publicintVertexCount;
}
Authoring Component:
publicclassDependentDataAuthoring:MonoBehaviour
{
    publicGameObjectOther;
    publicMeshMesh;
}

//定义从Authoring Compongt到ECS Component的Baker:
publicclassGetComponentBaker:Baker<DependentDataAuthoring>
{
    // Bake的时候调用Bake函数
    publicoverridevoidBake(DependentDataAuthoringauthoring)
    {
        // 声明所需要Baker的依赖关系
        DependsOn(authoring.Other);
        DependsOn(authoring.Mesh);

        if(authoring.Other == null)return;
        if(authoring.Mesh == null)return;

        vartransform = GetComponent<Transform>();
        vartransformOther = GetComponent<Transform>(authoring.Other);

        if(transform == null)return;
        if(transformOther == null)return;

        varentity = GetEntity(TransformUsageFlags.Dynamic);
        AddComponent(entity,newDependentData
        {
            Distance = Vector3.Distance(transform.position,transformOther.position),
            VertexCount = authoring.Mesh.vertexCount
        });
    }
}

  今天分享到这里,关注我们,学习更多的最新Unity DOTS 进阶与实战相关的知识.


  尊敬的准VIP客户:

  我们Unity DOTS课程也正式发布了,我们课程经过9年多的更新与迭代,已经涵盖了Unity 开发中遇到的绝大部分问题,涵盖了Unity主程序进阶,升职加薪所需要的系统的知识体系,主流游戏类型的重点难点技术解决方案。我们的老师10:00~23:00提供实时解答与回复,包含但不限于客户端+服务端。相信我们提供的游戏开发技术服务能很好的帮助到您。选择我们的VIP课程,您肯定不会后悔!有兴趣请 + 企.鹅.裙 428 540 563


  下面是DOTS的VIP课程前18节视频,免费观看

Unity DOTS进阶与项目实战(B站18集)

第001课DOTS的环境安装与准备事项

第002课 DOTS的核心机制与概述

第003课DOTS的SubScene

第004课Component的概述与普通组件的Baker

第005课System与SystemGroup概述

第006课DOTS中的ECS核心概念总结

第007课Baking系列之Baking与Baker详解

第008课Baking系列之BakingSystem与BakingWorld详解

第009课FilterBakingOutput与PrefabsInBaking

第010课BlobAsset核心机制分析

第011课Aspect核心机制分析

第012课 StructChange核心机制详解

第013课Managed与Unmanaged Component详解与性能分析

第014课ShareComponent核心机制与性能分析

第015课CleanupComponent核心分析

第016课 Dynamic Buffer Component详解与分析

第017课Tag与Chunk Component详解与分析

第018课Enableable与Singleton组件详解与分析

  • 23
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值