- 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.
Your answer