Skip to content

Jobify Entities Creation

What

Multiple entity creation is often sequential and unoptimised. This code pattern has a CreateEntity inside a loop:

// in System.OnUpdate
var commonInfo;
foreach (var info in constructionInfos) {
    var c1 = func1(info, commonInfo);
    Entity entity = EntityManager.CreateEntity();
    EntityManager.AddComponent(entity, c1);
    var c2 = func2(info, commonInfo, c1);
    EntityManager.AddComponent(entity, c2);
}

Why

This can be optimised by jobifying and run in parallel.

How

internal struct EntityJob : IJobParallelFor {
    [ReadOnly]
    public NativeArray<Entity> Entities;
    [ReadOnly]
    public NativeArray<Info> Infos;
    public CommonInfo CommonInfo;

    public ComponentLookup<C1> C1s;
    public ComponentLookup<C2> C2s;
    public void Execute(int index) {
        Entity entity = Entities[index];
        Info info = Infos[index];
        C1 c1 = C1s[entity] = func1(info, CommonInfo);
        C2s[entity] = func2(info, CommonInfo, c1);
    }
}
[BurstCompile]
internal partial struct CreateSystem : ISystem {
    private EntityArchetype _archetype;

    public void OnCreate(ref SystemState state) {
        _archetype = state.EntityManager.CreateArchetype(typeof(C1), typeof(C2));
    }

    public void OnUpdate(ref SystemState state) {
        NativeArray<Info> constructionInfos = ...;
        CommonInfo commonInfo = ...;

        NativeArray<Entity> entities = state.EntityManager.CreateEntity(_archetype, constructionInfos.Length, Allocator.TempJob);
        JobHandle handle = new EntityJob {
            Entities = entities,
            Infos = constructionInfos,
            CommonInfo = commonInfo,
            C1s = SystemAPI.GetComponentLookup<C1>(false),
            C2s = SystemAPI.GetComponentLookup<C2>(false),
        }.Schedule(entities.Length, your_inner_loop_batch_count);
        entities.Dispose(handle);
    }
}
Even though this solution uses ComponentLookup, it won't break Cache Locality because the newly created entities belong to the same chunk.