I am able to spawn entities in a job, but I’m not sure how to do it in a multithreaded job.
var spawndata = SystemAPI.GetSingleton<SpawnData>();
EntityCommandBuffer entityCommandBuffer = new EntityCommandBuffer(Allocator.TempJob);
EntityCommandBuffer.ParallelWriter parallelWriter = entityCommandBuffer.AsParallelWriter();
new TestSpawnMultithreaded
{
ecb = parallelWriter,
spawnData = spawndata,
}.ScheduleParallel();
[BurstCompile]
public partial struct TestSpawnMultithreaded : IJobEntity
{
public EntityCommandBuffer.ParallelWriter ecb;
public SpawnData spawnData;
void Execute([ChunkIndexInQuery] int chunkIndex)
{
var stone = new NativeArray<Entity>(25, Allocator.Temp);
var coal = new NativeArray<Entity>(20, Allocator.Temp);
ecb.Instantiate(chunkIndex, spawnData.Stone, stone);
ecb.Instantiate(chunkIndex, spawnData.Coal, coal);
}
}
Use IJobFor then use ScheduleParallel(). You’re not querying for anything.
The reason the code example IJobEntity is not querying for anything is because it is pseudo code. Assuming this code is using a Query (i.e. a turret that fires at targets), How would you Instantiate a entity using a multithreaded IJobEntity.
I barely use IJobEntity but it should be the same:
public struct SpawnJob : IJobChunk
{
public Entity prefab;
public EntityCommandBuffer.ParallelWriter commandBuffer;
public void Execute(in ArchetypeChunk chunk, int unfilteredChunkIndex, bool useEnabledMask, in v128 chunkEnabledMask)
{
for(...) {
Entity instance = commandBuffer.Instantiate(unfilteredChunkIndex, this.prefab);
// Prepare components of the instance here but use the commandBuffer
}
}
}
// Scheduling
SpawnJob spawnJob = new() {
prefab = yourPrefabEntity,
commandBuffer = commandBufferSystem.CreateCommandBuffer().AsParallelWriter()
};
this.Dependency = spawnJob.ScheduleParallel(yourQuery, this.Dependency);
Just a clarification. You are not spawning the entity in the job. You are registering a command to instantiate an entity later on.
The instantiation itself will happen in a single thread (most likely the main thread)
If you arent using one of the builtin ECBSystems, and you arent playing back your commands, all you are doing is recording (as there is no entityCommandBuffer.Playback in your example).
Is there a way to set Playback to work on other threads?
IJobEntity and IJobChunk only works with EntityQuery. Using IJobFor, IJob,IJobParallel do somthing in job