Iterate over component data with IJobEntity
You can use IJobEntity to iterate across ComponentData when you have a data transformation that you want to use in multiple systems, with different invocations. It creates an IJobChunk job, so you only have to consider what data you want to transform.
Note that IJobEntity works identically with SystemBase and ISystem.
Create an IJobEntity job
To create an IJobEntity job, write a struct that uses the IJobEntity interface, and implement your own custom Execute method.
Use the partial keyword because source generation creates a struct that implements IJobChunk in a separate file in project/Temp/GeneratedCode/.....
The following example adds one to every SampleComponent every frame.
public struct SampleComponent : IComponentData { public float Value; }
public partial struct ASampleJob : IJobEntity
{
    // Adds one to every SampleComponent value
    void Execute(ref SampleComponent sample)
    {
        sample.Value += 1f;
    }
}
public partial class ASample : SystemBase
{
    protected override void OnUpdate()
    {
        // Schedules the job
        new ASampleJob().ScheduleParallel();
    }
}
Specify a query
You can specify a query for IJobEntity in the following ways:
- Create a query manually, to specify different invocation requirements.
- Use the IJobEntityattributes to create a query based on its givenExecuteparameters, and specifications on the job struct.
The following example shows both options:
partial struct QueryJob : IJobEntity
{
    // Iterates over all SampleComponents and increments their value
    public void Execute(ref SampleComponent sample)
    {
        sample.Value += 1;
    }
}
[RequireMatchingQueriesForUpdate]
public partial class QuerySystem : SystemBase
{
    // Query that matches QueryJob, specified for `BoidTarget`
    EntityQuery query_boidtarget;
    // Query that matches QueryJob, specified for `BoidObstacle`
    EntityQuery query_boidobstacle;
    protected override void OnCreate()
    {
        // Query that contains all of Execute params found in `QueryJob` - as well as additional user specified component `BoidTarget`.
        query_boidtarget = GetEntityQuery(ComponentType.ReadWrite<SampleComponent>(),ComponentType.ReadOnly<BoidTarget>());
        // Query that contains all of Execute params found in `QueryJob` - as well as additional user specified component `BoidObstacle`.
        query_boidobstacle = GetEntityQuery(ComponentType.ReadWrite<SampleComponent>(),ComponentType.ReadOnly<BoidObstacle>());
    }
    protected override void OnUpdate()
    {
        // Uses the BoidTarget query
        new QueryJob().ScheduleParallel(query_boidtarget);
        // Uses the BoidObstacle query
        new QueryJob().ScheduleParallel(query_boidobstacle);
        // Uses query created automatically that matches parameters found in `QueryJob`.
        new QueryJob().ScheduleParallel();
    }
}
Attributes
IJobEntity has the following built-in attributes:
| Attribute | Description | 
|---|---|
| Unity.Entities.WithAll(params Type[]) | Set on the job struct. Narrows the query so that the entities have to match all the types provided. | 
| Unity.Entities.WithAny(params Type[]) | Set on the job struct. Narrows the query so that the entities have to match any of the types provided. | 
| Unity.Entities.WithNone(params Type[]) | Set on the job struct. Narrows the query so that the entities have to match none of the types provided. | 
| Unity.Entities.WithChangeFilter(params Type[]) | Set on the job struct or attach to an argument in Execute. Narrows the query so that the entities have to have had changes in the archetype chunk for the given components. | 
| Unity.Entities.WithOptions(params EntityQueryOptions[]) | Set on the job struct. Changes the scope of the query to use the EntityQueryOptionsdescribed. | 
| Unity.Entities.EntityIndexInQuery | Set on the intparameter inExecuteto get the current index in query, for the current entity iteration. This is the same asentityInQueryIndexinEntities.ForEach. | 
The following is an example of EntityIndexInQuery:
[BurstCompile]
partial struct CopyPositionsJob : IJobEntity
{
    public NativeArray<float3> copyPositions;
    // Iterates over all `LocalToWorld` and stores their position inside `copyPositions`.
    // The [EntityIndexInQuery] attribute provides the index of the current entity within the query results.
    public void Execute([EntityIndexInQuery] int entityIndexInQuery, in LocalToWorld localToWorld)
    {
        copyPositions[entityIndexInQuery] = localToWorld.Position;
    }
}
[RequireMatchingQueriesForUpdate]
public partial struct EntityInQuerySystem : ISystem
{
    // This query should match `CopyPositionsJob` parameters
    EntityQuery query;
    public void OnCreate(ref SystemState state)
    {
        // Get query that matches `CopyPositionsJob` parameters
        query = state.GetEntityQuery(ComponentType.ReadOnly<LocalToWorld>());
    }
    public void OnUpdate(ref SystemState state)
    {
        // Get a native array equal to the size of the amount of entities found by the query.
        var positions = new NativeArray<float3>(query.CalculateEntityCount(), state.WorldUnmanaged.UpdateAllocator.ToAllocator);
        // Schedule job on parallel threads for this array.
        // The EntityIndexInQuery parameter ensures each entity gets a unique index for array access.
        new CopyPositionsJob{copyPositions = positions}.ScheduleParallel();
        // Dispose the array of positions found by the job.
        positions.Dispose(state.Dependency);
    }
}
Because IJobEntity is a job, you can also use all attributes that work on a job:
- Unity.Burst.BurstCompile
- Unity.Collections.DeallocateOnJobCompletion
- Unity.Collections.NativeDisableParallelForRestriction
- Unity.Burst.BurstDiscard
- Unity.Collections.LowLevel.Unsafe.NativeSetThreadIndex
- Unity.Collections.NativeDisableParallelForRestriction
- Unity.Burst.NoAlias
Execute parameters
The following is a list of all the supported Execute parameters you can use in IJobEntity:
| Parameter | Description | 
|---|---|
| IComponentData | Mark as reffor read-write access, orinfor read-only access to theComponentData. | 
| ICleanupComponentData | Mark as reffor read-write access, orinfor read-only access to theComponentData. | 
| ISharedComponent | Mark infor read-only access to aSharedComponentData. If this is managed you can't Burst compile or schedule it. Use.Runinstead. | 
| Managed components | Use a value-copy for read-write access or mark with infor read-only access of managed components. For example,UnityEngine.Transform. Marking a managed component asrefis an error, and you can't Burst-compile or schedule it. Use.Runinstead. | 
| Entity | Gets the current entity. This is a value copy only, so don't mark with reforin. | 
| DynamicBuffer<T> | Gets the DynamicBuffer. Mark withreffor read-write access andinfor read-only access. | 
| IAspect | Gets the Aspect. Aspects act as references so you can't assign them. However, you can use refand value-copy to mark it as read-write, andinfor read-only access. | 
| int | There are three supported ints: 
 |