赞
踩
最近DOTS终于发布了正式的版本, 我们来分享一下DOTS里面Baking阶段,Baking System,Baking World的关键概念,方便大家上手学习掌握Unity DOTS开发。Unity在Baking也是基于ECS模式开发设计的,所以Baking的时候也会有Baking System与Baking World,把Baking出来的数据放到Baking World里面。
Baking 的主要阶段
在Baker阶段执行之前,Unity会把subscene中所有的Authoring GameObject创建出对应的entity,这个阶段entity不包含任何组件数据,只包含一些metadata的描述数据。创建完Entity以后,就会执行Bakers 每个Baker处理对应它的authoring component的数据转化。每种类型的数据对应一种Baker,例如Entities Graphics就会有Baker将GameObject的渲染数据转换成renderers的数据。Unity Physics有Baker 把刚体RigidBody组件转成ecs数据。相同的类型只要一种Baker就即可。
PreBakingSystemGroup: 这个System分组执行发生在所有Bakers运行之前;
TransformBakingSystemGroup: 是一个用于处理实体的变换信息的系统组。它负责将实体的Transform数据进行烘焙,以提高性能和优化渲染。
实时Baking时,Unity会运行所有的baking system分组,它会把entity数据存入到entity scene,并序列化到磁盘。并把烘培出来后变化的数据同步到main ECS World里面。
Baking World
Unity 在Baker 每个entity scene的时候都是独立的。每次只处理一个场景。同时每个独立的场景都有一个独立的main world。同时在Baker每个场景的时候,我们的Unity会额外分配两个世界:
Unity 会在 Conversion world 里面来运行Baker与Baking Sytems来做场景物体的Baking。当Baking结束以后,Unity Baking比较Shadow World与Conversion World的变化,看哪些改变了,Unity只把本次改变同步给main World。
Baking System
Baking System 是一种机制,被用于批量处理ecs components与entities的数据。一个Baking System在Unity DOTS内部也是一个System,它基于多线程与Burst 编译器,能够很好做批量的处理。Baking System与Baker机制不同的点在于Baker是将authoring data一个一个的处理转换,然后
创建一个Baking System,我们需要给Baking System加上[WorldSystemFilter(WorldSystemFilterFlags.BakingSystem)]的注解。加了这个注解,我们系统Baker处理就会把它识别出来,并把它加入到Baking World里面来进行迭代。Unity每次Baking,都会迭代World里面的所有Baking System。接下来我们看一个Baking System 添加一个tag component到包含的某A组件的entity中的示例代码:
public struct AnotherTag : IComponentData { }
[WorldSystemFilter(WorldSystemFilterFlags.BakingSystem)]
partial struct AddTagToRotationBakingSystem : ISystem
{
public void OnUpdate(ref SystemState state)
{
var queryMissingTag = SystemAPI.QueryBuilder()
.WithAll<RotationSpeed>()
.WithNone<AnotherTag>()
.Build();
state.EntityManager.AddComponent<AnotherTag>(queryMissingTag);
// Omitting the second part of this function would lead to inconsistent
// results during live baking. Added tags would remain on the entity even
// after removing the RotationSpeed component.
var queryCleanupTag = SystemAPI.QueryBuilder()
.WithAll<AnotherTag>()
.WithNone<RotationSpeed>()
.Build();
state.EntityManager.RemoveComponent<AnotherTag>(queryCleanupTag);
}
}
定义了一个Baking System, 每次迭代update的时候,找出World中所有包含RotationSpeed组件并且不含AnotherTag组件的Entity的集合,给它们加上AnotherTag组件,找出所有不包含RotationSpeed且包含AnotherTag的Entity集合,把它们的AnotherTag删除掉。
今天的Baking Phase, Baking World与Baking System就分享到这里了,关注我学习更多的最新Unity DOTS开发技巧。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。