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 MeshInstanceRenderer between many Boid entities is exactly the same.
[System.Serializable]
public struct MeshInstanceRenderer : ISharedComponentData
{
public Mesh mesh;
public Material material;
public ShadowCastingMode castShadows;
public bool receiveShadows;
}In the Boid demo we never change the MeshInstanceRenderer component, but we do move all the entities' Transform every frame.
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.
- Entities with the same
SharedComponentDataare grouped together in the same Chunks. The index to theSharedComponentDatais stored once perChunk, not perEntity. As a resultSharedComponentDatahave zero memory overhead on a perEntitybasis. - Using
ComponentGroupwe can iterate over all entities with the same type. - Additionally we can use
ComponentGroup.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 thatEntityinto a differentChunk.