原文: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複製到另一個塊中。