Use an entity command buffer
You can record entity command buffers (ECBs) in jobs, and on the main thread.
Use an entity command buffer in a job
You can't perform structural changes in a job, except inside an ExclusiveEntityTransaction
, so you can use an ECB to record structural changes to play back after the job is complete. For example:
protected override void OnUpdate()
{
// You don't specify a size because the buffer will grow as needed.
EntityCommandBuffer ecb = new EntityCommandBuffer(Allocator.TempJob);
// The ECB is captured by the ForEach job.
// Until completed, the job owns the ECB's job safety handle.
Entities
.ForEach((Entity e, in FooComp foo) =>
{
if (foo.Value > 0)
{
// Record a command that will later add BarComp to the entity.
ecb.AddComponent<BarComp>(e);
}
}).Schedule();
Dependency.Complete();
// Now that the job is completed, you can enact the changes.
// Note that Playback can only be called on the main thread.
ecb.Playback(EntityManager);
// You are responsible for disposing of any ECB you create.
ecb.Dispose();
}
Parallel jobs
If you want to use an ECB in a parallel job, use EntityCommandBuffer.ParallelWriter
, which concurrently records in a thread-safe way to a command buffer:
EntityCommandBuffer ecb = new EntityCommandBuffer(Allocator.TempJob);
// Methods of this writer record commands to
// the EntityCommandBuffer in a thread-safe way.
EntityCommandBuffer.ParallelWriter parallelEcb = ecb.AsParallelWriter();
Note
Only recording needs to be thread-safe for concurrency in parallel jobs. Playback is always single-threaded on the main thread.
For information on deterministic playback in parallel jobs, refer to the documentation on Entity command buffer playback
Use an entity command buffer on the main thread
You can record ECB changes on the main thread, such as in the following situations:
- To delay your changes.
- To play back a set of changes multiple times. To do this, refer to the information on multi-playback.
- To play back a lot of different kinds of changes in one consolidated place. This is more efficient than interspersing the changes across different parts of the frame.
Every structural change operation triggers a sync point, which means that the operation must wait for some or all scheduled jobs to complete. If you combine the structural changes into an ECB, the frame has fewer sync points.
Note
If you have a lot of the same types of commands in an ECB, and you can afford to make the change instantly, it can be faster to use the EntityManager variants on whole batches of entities at once.