So I read @5argon blog post over here this morning https://gametorrahod.com/unity-ecs-batched-operation-on-entitymanager-3c35e8e5ecf4
And as I use quite a few short lived event entities in my project I was curious if I could write something that could generically replaced EntityCommandBuffer for these. So I did!
Firstly code, this is my first, not well tested and quickly written proof of concept.
-edit- dramatically updating code, will post it when i’m done.
-edit2- latested post here, now 3x faster than original version (10x faster than a barrier): Batch EntityCommandBuffer - Unity Engine - Unity Discussions
How it works. It passes a NativeQueue whenever requested.
Get the barrier with this.batchBarrier = this.World.GetOrCreateManager<BatchBarrierSystem>(); The same barrier is used for all systems.
To create an entity use
NativeQueue<T>.Concurrent createQueue = this.batchBarrier.GetCreateQueue<T>().ToConcurrent();
where T is an IComponentData that will be added and set on the entity.
Then just pass it to a job, for example
[BurstCompile]
private struct CreateEntitiesJob : IJobParallelFor
{
public NativeQueue<TestComponent>.Concurrent AddComponentQueue;
/// <inheritdoc />
public void Execute(int index)
{
this.AddComponentQueue.Enqueue(new TestComponent { Index = index });
}
}
To destroy an entity, use the
NativeQueue<Entity>.Concurrent = this.batchBarrier.GetDestroyQueue().ToConcurrent(),
Any entity added to this queue will be destroyed.
[BurstCompile]
private struct DestroyEntitiesJob : IJobProcessComponentDataWithEntity<TestComponent>
{
public NativeQueue<Entity>.Concurrent DestroyEntityQueue;
/// <inheritdoc />
public void Execute(Entity entity, int index, ref TestComponent data)
{
this.DestroyEntityQueue.Enqueue(entity);
}
}
The one extra bit you need to do atm is pass the dependency to the system because I don’t have any access to AfterUpdate();
this.batchBarrier.AddDependency(handle);
return handle;
Why bother?
At the moment it is about 3x faster than using EntityCommandBuffers and completely garbage free.
Also it works in Burst jobs
I believe I could probably optimize it quite a bit if I limit the use.
100,000 entities being added and removed each frame.
This is done in a build (with profiler attached obviously)
I’m not sure why endframebarrier is throwing garbage.