Unity ECS 03 共享组件

原文:https://docs.unity3d.com/Packages/[email protected]/manual/shared_component_data.html

共享组件是一种特殊的数据组件,可用于根据共享组件中的特定值(除了原型之外)对实体进行细分。 将共享组件添加到实体时,EntityManager会将具有相同共享数据值的所有实体放入同一块中。
共享组件使您的系统可以像实体一样一起处理。 例如,作为Hybrid.rendering包一部分的共享组件Rendering.RenderMesh定义了几个字段,包括网格,材质和receiveShadows。 当您的应用程序渲染时,最有效的方法是一起处理所有具有相同字段值的3D对象。 因为共享组件指定了这些属性,所以EntityManager将匹配的实体放置在内存中临近的区域,以便渲染系统可以有效地对其进行迭代。

注意:如果您过度使用共享组件,则可能导致不佳的块利用率。 这是因为当您使用共享组件时,它涉及基于原型和每个共享组件字段的每个唯一值的内存块数量的组合扩展。 因此,请避免添加将实体归类到共享组件中不需要的任何字段。 要查看块利用率,请使用实体调试器。

如果您从实体中添加或删除组件,或更改共享组件的值,则EntityManager会将实体移至其他块,并在必要时创建新块。

您应该将IComponentData用于不同实体之间变化的数据,例如存储世界位置,特工生命值或粒子生存时间。 相反,当许多实体共享某些共同点时,应使用ISharedComponentData。 例如,在DOTS软件包的Boids演示中,许多实体是从同一Prefab实例化的,因此,许多Boid实体之间的RenderMesh完全相同。

[System.Serializable]
public struct RenderMesh : ISharedComponentData
{
    public Mesh                 mesh;
    public Material             material;

    public ShadowCastingMode    castShadows;
    public bool                 receiveShadows;
}

ISharedComponentData每个实体的内存成本为零。 您可以使用ISharedComponentData将具有相同InstanceRenderer数据的所有实体放在一起,然后高效地访问矩阵来进行渲染。 由于ECS访问数据时会对数据进行布局,因此生成的代码既简单又高效。

关于SharedComponentData的重要说明

ECS将具有相同SharedComponentData的实体按相同的块分组在一起。 它将每个块而不是每个实体一次存储到SharedComponentData的索引。 因此,每个实体的SharedComponentData的内存开销为零。

您可以使用EntityQuery遍历具有相同类型的所有实体。 您还可以使用EntityQuery.SetFilter()专门对具有特定SharedComponentData值的实体进行迭代。 由于数据布局的原因,此迭代的开销很低。

您可以使用EntityManager.GetAllUniqueSharedComponents检索添加到任何活动实体的所有唯一SharedComponentData。

ECS自动对SharedComponentData进行引用计数

SharedComponentData应该很少更改。 如果要更改SharedComponentData,则涉及使用memcpy将该实体的所有ComponentData复制到另一个块中。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章