Modify dynamic buffers with an entity command buffer
An EntityCommandBuffer
(ECB) records commands to add, remove, or set buffer components for entities. There are dynamic buffer-specific APIs that are different than the regular component APIs.
An ECB can only record commands to happen in the future, so it can only manipulate dynamic buffer components in the following ways:
SetBuffer<T>
: Returns aDynamicBuffer<T>
that the recording thread can populate with data. At playback, these buffer contents overwrite any existing buffer contents.SetBuffer
doesn’t fail if the target entity already contains the buffer component. If more than one thread records aSetBuffer
command on the same entity, after playback only the contents added by the last command according tosortKey
order are visible.SetBuffer
has the same functionality asAddBuffer<T>
, exceptAddBuffer
adds the buffer to the component first, if it doesn't exist.AppendToBuffer<T>
: Appends a single buffer element to an existing buffer component on an entity, and preserves any existing buffer contents. Multiple threads can safely append to the same buffer component on the same entity and thesortKey
of the recorded commands determines the order of the resulting elements.AppendToBuffer<T>
fails at playback if the target entity doesn’t contain a buffer component of typeT
. Therefore, it's best practice to precede everyAppendToBuffer
command withAddComponent<T>
, to ensure that the target buffer component is present.- You can safely use the
AddComponent<T>
andRemoveComponent<T>
methods ifT
is anIBufferElementData
to add an empty buffer or remove an existing buffer. These methods are safe to use from multiple threads and adding an existing component or removing a non-existent component doesn't cause an error.
The following code example walks through some general dynamic buffer-specific EntityCommandBuffer
APIs. It assumes a dynamic buffer called MyElement
exists.
private void Example(Entity e, Entity otherEntity)
{
EntityCommandBuffer ecb = new(Allocator.TempJob);
// Record a command to remove the MyElement dynamic buffer from an entity.
ecb.RemoveComponent<MyElement>(e);
// Record a command to add a MyElement dynamic buffer to an existing entity.
// This doesn't fail if the target entity already contains the buffer component.
// The data of the returned DynamicBuffer is stored in the EntityCommandBuffer,
// so changes to the returned buffer are also recorded changes.
DynamicBuffer<MyElement> myBuff = ecb.AddBuffer<MyElement>(e);
// After playback, the entity will have a MyElement buffer with
// Length 20 and these recorded values.
myBuff.Length = 20;
myBuff[0] = new MyElement { Value = 5 };
myBuff[3] = new MyElement { Value = -9 };
// SetBuffer is like AddBuffer, but safety checks will throw an exception at playback if
// the entity doesn't already have a MyElement buffer.
DynamicBuffer<MyElement> otherBuf = ecb.SetBuffer<MyElement>(otherEntity);
// Records a MyElement value to append to the buffer. Throws an exception at
// playback if the entity doesn't already have a MyElement buffer.
// ecb.AddComponent<MyElement>(otherEntity) is a safe way to ensure a buffer
// exists before appending to it.
ecb.AppendToBuffer(otherEntity, new MyElement { Value = 12 });
}
When you set the Length
, Capacity
, and content of the DynamicBuffer
, ECS records those changes into the EntityCommandBuffer
. When you play back the EntityCommandBuffer
, ECS makes the changes to the dynamic buffer.