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
SharedComponentDataare grouped together in the same Chunks. The index to theSharedComponentDatais stored once perChunk, not per entity. As a resultSharedComponentDatahave zero memory overhead on a per entity basis. - Using
EntityQuerywe can iterate over all entities with the same type. - Additionally we can use
EntityQuery.SetFilter()to iterate specifically over entities that have a specificSharedComponentDatavalue. Due to the data layout this iteration has low overhead. - Using
EntityManager.GetAllUniqueSharedComponentswe can retrieve all uniqueSharedComponentDatathat is added to any alive entities. SharedComponentDataare automatically reference counted.SharedComponentDatashould change rarely. Changing aSharedComponentDatainvolves using memcpy to copy allComponentDatafor that entity into a differentChunk.