Accessing zero-length (tag) components using Entities.ForEach

I’m testing out the different ways of querying entities and am learning about some of the patterns that current ECS users are using. I’m attracted to the idea of using tag components with no data to better group my entities. I’m also interested in the new ForEach lambda, but when I use it to make a query that includes tag components, I see runtime exceptions. Tags work all right in IJobForEach.

I understand that ForEach generates high-efficiency boilerplate, and that this may be what precludes using a tag in one. However, I wanted to double check to see whether:

  1. There is a convenient way to use tags with ForEach that I’m missing, since I’m just starting to learn ECS conventions.

  2. If not, whether the ForEach codegen eventually will accommodate zero-length components.

Here is the ForEach that throws exceptions:

public class TagSystem_ForEach : JobComponentSystem {
   
    protected override JobHandle OnUpdate( JobHandle inputDependencies ) {
        float deltaTime = Time.DeltaTime;
       
        var jobHandle = Entities.ForEach( (
               ref Translation translation,
               in Player playerTag
            ) => {
                translation.Value = new float3( translation.Value.x + deltaTime, translation.Value.y, translation.Value.z );
            }
        ).Schedule( inputDependencies );
       
        return jobHandle;
    }
}

Here is the IJobForEach that doesn’t.

public class TagSystem : JobComponentSystem {
   
    [BurstCompile]
    struct TagSystemJob : IJobForEach<Translation, Player> {
        public float deltaTime;
       
        public void Execute( ref Translation translation, [ReadOnly] ref Player playerTag ) {
            translation.Value = new float3( translation.Value.x + deltaTime, translation.Value.y, translation.Value.z );
        }
    }
   
    protected override JobHandle OnUpdate( JobHandle inputDependencies ) {
       
        var job = new TagSystemJob { deltaTime = Time.DeltaTime };
        return job.Schedule( this, inputDependencies );
    }
}

The exception is:

System.ArgumentException: ArchetypeChunk.GetNativeArray<{0}> cannot be called on zero-sized IComponentData

Include tag components via WithAll instead of ForEach:

var jobHandle = Entities.WithAll<PlayerTag>().ForEach( (
           ref Translation translation
        ) => {
            translation.Value = new float3( translation.Value.x + deltaTime, translation.Value.y, translation.Value.z );
        }
    ).Schedule( inputDependencies );
JobHandle jobHandleForEach = Entities
                // filters are used for components that won't be used in job for read/write (thos are parameters)
                .WithName("foreach_inline_job")                                             // name of the job in debugger
                .WithNone<MyAtomData2>()                                                    // filter out any Entities with the component
                .WithAny<MyAtomData4, MyAtomData5>()                                        // require either component for entity to be included in filter
                .WithAll<MyAtomData6, MyAtomData7>()                                        // require all components for entity to be included in filter
                .WithEntityQueryOptions(EntityQueryOptions.IncludeDisabled)                 // include entities with the special Disabled component
                .WithBurst(FloatMode.Default, FloatPrecision.Standard, false)               // burst settings (set true for synchronous mode)
                .ForEach((Entity entity, int entityInQueryIndex, in MyAtomData3 myAtomData3) =>  // Entity entity = currently passed entity, entityInQueryIndex = the current index of the array of entities passed in, in = read only, ref = write
              
                {
3 Likes

Great! Thanks for the help.

hey Marble, thanks for the report! as others mention here, you can use .WithAll<>(), but what you were doing makes total sense, and we should just make that work, or at the very least give you a 10x better error message.

5 Likes