AddComponent from inside JobComponentSystem Job?

Hey everyone,
I’m trying to add a component inside a JobComponentSystem Job.
I can do it just fine with a ComponentSystem by simply passing in the PostUpdateCommands as a EntityCommandBuffer but it does not exist inside a JobComponentSystem.

Example Code:

    private struct Job : IJobForEachWithEntity<Translation> {

        public EntityCommandBuffer entityCommandBuffer;

        public void Execute(Entity entity, int index, ref Translation translation) {
            entityCommandBuffer.AddComponent(entity, new MyComponent());
        }

    }


    protected override JobHandle OnUpdate(JobHandle inputDeps) {
        Job job = new Job {
            entityCommandBuffer = ???????
        };
        return job.Schedule(this, inputDeps);
    }

All the help I can find online is using the Barrier system which I believe has been deprecated.

How do I create a EntityCommandBuffer that runs after the job? Or should I be using something else entirely?

You pass in a command buffer to use in the job. The barrier systems are still there, they’ve just been renamed. For example: EndSimulationEntityCommandBufferSystem

See docs here:
https://docs.unity3d.com/Packages/com.unity.entities@0.0/manual/system_update_order.html

You can also use PostUpdateCommands which I believe are run right after the current system finishes running.

1 Like

In your example it would look something like this.

private EndSimulationEntityCommandBufferSystem entityCommandBufferSystem;

private struct Job : IJobForEachWithEntity<Translation> {
    public EntityCommandBuffer entityCommandBuffer;
    public void Execute(Entity entity, int index, ref Translation translation) {
        entityCommandBuffer.AddComponent(entity, new MyComponent());
    }
}

protected override void OnCreate()
{
    entityCommandBufferSystem = World.GetOrCreateSystem<EndSimulationEntityCommandBufferSystem>();
    base.OnCreate();
}

protected override JobHandle OnUpdate(JobHandle inputDeps) {
    Job job = new Job {
        entityCommandBuffer = entityCommandBufferSystem.CreateCommandBuffer()
    };
    return job.Schedule(this, inputDeps);
}

Many thanks! It works now, needed to get the system from the World then create a CommandBuffer and finally AddJobHandleForProducer.

Here’s my final code in case someone finds this thread in the future:

private struct Job : IJobForEachWithEntity<Translation> {
    public EntityCommandBuffer.Concurrent entityCommandBuffer;
    public void Execute(Entity entity, int index, ref Translation translation) {
        entityCommandBuffer.AddComponent(index, entity, new MyComponent());
    }
}
private EndSimulationEntityCommandBufferSystem endSimulationEntityCommandBufferSystem;

protected override void OnCreate() {
    endSimulationEntityCommandBufferSystem = World.GetOrCreateSystem<EndSimulationEntityCommandBufferSystem>();
    base.OnCreate();
}

protected override JobHandle OnUpdate(JobHandle inputDeps) {
    Job job = new Job {
        entityCommandBuffer = endSimulationEntityCommandBufferSystem.CreateCommandBuffer().ToConcurrent(),
    };
    JobHandle jobHandle = job.Schedule(this, inputDeps);

    endSimulationEntityCommandBufferSystem.AddJobHandleForProducer(jobHandle);

    return jobHandle;
}

Thanks again!

6 Likes