How to have a combined archetype in a Job

I am trying to create a archetype of 2 types (1: entity with select tag 2: ring with a UI tag) to iterate over a job.

They are separate entities that both have a transform.

If this can be done In IJobEntity I would prefer that.

//What i'm trying to achieve.
[BurstCompile]
partial struct SelectUIJob : IJobEntity
{
    void Execute(in SelectRingData data, ref LocalTransform ringtransform, /* 2nd entity*/ in SelectedEntities selectedEntities, in LocalToWorld ltw)
    {

    }
}






















I’ve tried IJobChunk but the example in the docs appears to be for a single archetype.

 var query = SystemAPI.QueryBuilder().WithAll<SelectRingData>().WithAll<LocalTransform>().AddAdditionalQuery().WithAll<LocalToWorld>().WithAll<SelectedEntities>().Build();
 state.EntityManager.AddChunkComponentData(query, new TestCombineChunk());

 state.Dependency = new SelectUIChunkJob
 {
     SelectedLTWHandle = SystemAPI.GetComponentTypeHandle<LocalToWorld>(),
     RingTransformHandle = SystemAPI.GetComponentTypeHandle<LocalTransform>(),
 }.ScheduleParallel(SystemAPI.QueryBuilder().WithAll<TestCombineChunk>().Build(), state.Dependency);
[BurstCompile]
partial struct SelectUIChunkJob : IJobChunk
{
    public ComponentTypeHandle<LocalToWorld> SelectedLTWHandle;
    public ComponentTypeHandle<LocalTransform> RingTransformHandle;
    public void Execute(in ArchetypeChunk chunk, int unfilteredChunkIndex, bool useEnabledMask, in v128 chunkEnabledMask)
    {
        var SelectedLTW = chunk.GetNativeArray(ref SelectedLTWHandle);
        var ringtransforms = chunk.GetNativeArray(ref RingTransformHandle);

        var enumerator = new ChunkEntityEnumerator(useEnabledMask, chunkEnabledMask, chunk.Count);

        while (enumerator.NextEntityIndex(out int i))
        {

            var ring = ringtransforms[i];
            ring.Position = SelectedLTW[i].Position;

            ringtransforms[i] = ring;
        }

    }
}

You are trying to get two separate entities into a single Execute() call? What is the mapping supposed to be? How should Unity decide to form the pairs?

If I understand correctly, you’re setting the position stored in SelectedLTW to ringTransforms. But it doesn’t make sense since there’s no mapping from SelectedLTW to the ringsTransform.

You find that mapping, and what you do is you collect the the SelectedLTW positions in a container, say NativeParallelHashMap<int, float3> if your mapping is an int id (just an example). You can populate this container using a separate job on a query that only queries entities with SelectedLTW.

Then you can pass this map on another job that sets the position stored here into the ring entities. Thiw will work on another query that only gets the rings. Something like this:

partial struct SetPositionsJob : IJobChunk {
    ...

    [ReadOnly]
    public NativeParallelHashMap<int, float3> selectedLtwPositions;

    public void Execute(in ArchetypeChunk chunk, int unfilteredChunkIndex, bool useEnabledMask, in v128 chunkEnabledMask) {
        var ringInfos = chunk.GetNativeArray(...);
        var ringTransforms = chunk.GetNativeArray(...);

        while(...) {
            RingInfo ring = ringInfos[i];
            float3 position = selectedLtwPositions[ring.Id]; // This is the mapping

            LocalTransform ringTransform = ringTransforms[i];
            ringTransform.position = position;
            ringTransforms[i] = ringTransform; // Modify
        }
    }
}