Hello, I have slight issue with my code. I have created basic ecs (hybrid(with monobehaviour)) script where i have jobified for function that creates grid of entities using entity command buffer. It works as it should and indeed creates the entities, but it also creates error when i activate it. The error is:
.
InvalidOperationException: The previously scheduled job TileGeneration writes to the NativeArray TileGeneration.ECB. You are trying to schedule a new job TileGeneration, which writes to the same NativeArray (via TileGeneration.ECB). To guarantee safety, you must include TileGeneration as a dependency of the newly scheduled job.
Unity.Jobs.LowLevel.Unsafe.JobsUtility.Schedule (Unity.Jobs.LowLevel.Unsafe.JobsUtility+JobScheduleParameters& parameters) (at :0)
Unity.Jobs.IJobExtensions.Schedule[T] (T jobData, Unity.Jobs.JobHandle dependsOn) (at :0)
Generation.TileGenerate () (at Assets/Generation.cs:72)
Generation.Update () (at Assets/Generation.cs:52)
.
The code appears completely right and does not show errors. What i figured out is that there is some nitpicky stuff going on that causes it but i couldnt figure it out. Althought it works fine i wnat to get rid of it as it may become real problem in the future. Could you guys please help me? Heres the entire code. I am sorry if it shows in bad way.
.
public class Generation : Monobehaviour
{
EntityManager EntityManager;
EndSimulationEntityCommandBufferSystem ECBS;
EntityCommandBuffer ECB;
EntityArchetype TileArchetype;
public int Width;
public int Height;
public float TileSize;
public Vector2 OriginPosition;
private void Start()
{
EntityManager = World.DefaultGameObjectInjectionWorld.EntityManager;
ECBS = World.DefaultGameObjectInjectionWorld.GetOrCreateSystem<EndSimulationEntityCommandBufferSystem>();
TileArchetype = EntityManager.CreateArchetype
(
typeof(Translation)
);
}
private void Update()
{
ECB = ECBS.CreateCommandBuffer();
if (Input.GetKeyDown(KeyCode.Space))
{
JobHandle JobHandle = TileGenerate();
JobHandle.Complete();
}
}
private JobHandle TileGenerate()
{
TileGeneration GenerationJob = new TileGeneration();
GenerationJob.TileArchetype = TileArchetype;
GenerationJob.ECB = ECB;
GenerationJob.Width = Width;
GenerationJob.Height = Height;
GenerationJob.TileSize = TileSize;
GenerationJob.OriginPosition = OriginPosition;
JobHandle JobHandle = GenerationJob.Schedule();
ECBS.AddJobHandleForProducer(JobHandle);
return GenerationJob.Schedule();
}
}
public struct TileGeneration : IJob
{
public EntityCommandBuffer ECB;
public EntityArchetype TileArchetype;
public int Width;
public int Height;
public float TileSize;
public Vector2 OriginPosition;
public void Execute()
{
for (int x = 0; x < Width; x++)
{
for (int y = 0; y < Height; y++)
{
Entity Entity = ECB.CreateEntity(TileArchetype);
ECB.SetComponent(Entity, new Translation { Value = new float3(((float)x * TileSize + OriginPosition.x) + TileSize * 0.5f, ((float)y * TileSize + OriginPosition.y) + TileSize * 0.5f, 0) });
}
}
}
}