Shared ComponentData
IComponentData
is appropriate for data that varies between entities, such as storing a World
position. ISharedComponentData
is useful when many entities have something in common, for example in the Boid
demo we instantiate many entities from the same Prefab and thus the RenderMesh
between many Boid
entities is exactly the same.
[System.Serializable]
public struct RenderMesh : ISharedComponentData
{
public Mesh mesh;
public Material material;
public ShadowCastingMode castShadows;
public bool receiveShadows;
}
The great thing about ISharedComponentData
is that there is literally zero memory cost on a per entity basis.
We use ISharedComponentData
to group all entities using the same InstanceRenderer
data together and then efficiently extract all matrices for rendering. The resulting code is simple & efficient because the data is laid out exactly as it is accessed.
RenderMeshSystemV2
(see file: Packages/com.unity.entities/Unity.Rendering.Hybrid/RenderMeshSystemV2.cs)
Some important notes about SharedComponentData:
- Entities with the same
SharedComponentData
are grouped together in the same Chunks. The index to theSharedComponentData
is stored once perChunk
, not per entity. As a resultSharedComponentData
have zero memory overhead on a per entity basis. - Using
EntityQuery
we can iterate over all entities with the same type. - Additionally we can use
EntityQuery.SetFilter()
to iterate specifically over entities that have a specificSharedComponentData
value. Due to the data layout this iteration has low overhead. - Using
EntityManager.GetAllUniqueSharedComponents
we can retrieve all uniqueSharedComponentData
that is added to any alive entities. SharedComponentData
are automatically reference counted.SharedComponentData
should change rarely. Changing aSharedComponentData
involves using memcpy to copy allComponentData
for that entity into a differentChunk
.