- Home /
[ECS] Create Entities from Job ( IJobForEachWithEntity) using an EntityCommandBuffer
Hello there,
i'm currently trying to learn using the ECS and i currently struggel with the following problem: Given a job on an Archetype i want to create more of these entities under some conditions. So far i could not manage to get the entitycommandbuffer to work, which you need since one cannot create more entities from a job.
My Struct setup looks as follows:
struct CollisionJob : IJobForEachWithEntity<NodeStruct, CubeCollisionData>
{
public EntityArchetype _NodeArchetype;
public EntityCommandBuffer _entityCommandBuffer;
//public EntityArray entityArray;
public void Execute(Entity e, int i, [ReadOnly] ref NodeStruct Node, [ReadOnly] ref CubeCollisionData colObject)
{
////Divide:
if (!Node.split)
{
for (int j = 0; j < 8; j++)
{
_entityCommandBuffer.CreateEntity(_NodeArchetype);
}
}
Node.split = true;
}
}
protected override JobHandle OnUpdate(JobHandle inputDeps)
{
if (Input.GetKeyDown(KeyCode.Space))
{
return (new CollisionJob { _NodeArchetype = NodeArchetype, _entityCommandBuffer = entityCommandBuffer}).Schedule(this, inputDeps);
}
return inputDeps;
}
So far i have tried creating an entityCommandBuffer and a Concurrent EntityCommandBuffer in the main Thread using
World.Active.EntityManager.World.GetOrCreateSystem<BeginSimulationEntityCommandBufferSystem>().CreateCommandBuffer().ToConcurrent()
which only results in an error telling me that the commandbuffer was not initialized when i try to use it...
Some insight on this is highly appreaceated since i cannot find any valid information on this...
Thanks in advance!
Answer by Captain_Pineapple · Jul 26, 2019 at 12:28 PM
Well for those who are intrested:
solution was the following:
protected override void OnCreate()
{
entityCommandBuffer = World.GetOrCreateSystem<EndSimulationEntityCommandBufferSystem>();
}
Create a "Startfunction" for your System class. There have it instantiate a fitting 'CommandBufferSystem'. In my case an 'EndSImulationEntityCommandBufferSystem'. From what i understand they are only different in their time of execution. Then change the OnUpdate call as below:
struct CollisionJob : IJobForEachWithEntity<NodeStruct, CubeCollisionData>
{
public EntityArchetype _NodeArchetype;
public EntityCommandBuffer _entityCommandBuffer;
public void Execute(Entity e, int i, [ReadOnly] ref NodeStruct Node, [ReadOnly] ref CubeCollisionData colObject)
{
////Divide:
if (!Node.split)
{
for (int j = 0; j < 8; j++)
{
_entityCommandBuffer.CreateEntity(_NodeArchetype);
}
}
Node.split = true;
}
}
protected override JobHandle OnUpdate(JobHandle inputDeps)
{
if (Input.GetKeyDown(KeyCode.Space))
{
return (new CollisionJob { _NodeArchetype = NodeArchetype, _entityCommandBuffer = entityCommandBuffer.CreateCommandBuffer().ToConcurrent()}).Schedule(this, inputDeps);
}
entityCommandBuffer.AddJobHandleForProducer(colJob);
return inputDeps;
}
This worked for me. Let me know if i missed something in here.
Cheers.