protected override JobHandle OnUpdate(JobHandle inputDeps) { // First gather the state data we want to operate on. // We want both entity and translation information about the target, so extract this from the target query. var targetEntities = targetsQuery.ToEntityArray(Allocator.TempJob); var targetTranslations = targetsQuery.ToComponentDataArray <LocalToWorld>(Allocator.TempJob); var targetVelocities = targetsQuery.ToComponentDataArray <PhysicsVelocity>(Allocator.TempJob); // Construct a new array that merges the two data types together into simple structs. var targetArray = new NativeArray <TargetingSystemUtils.EntityWithPosition>(targetEntities.Length, Allocator.TempJob); for (int i = 0; i < targetArray.Length; i++) { targetArray[i] = new TargetingSystemUtils.EntityWithPosition { entity = targetEntities[i], position = targetTranslations[i].Position, velocity = targetVelocities[i].Linear, }; } // Clear up the intermediate native arrays; the native arrays passed to jobs are marked to be automatically deallocated. targetEntities.Dispose(); targetTranslations.Dispose(); targetVelocities.Dispose(); // We need to extract the closest target per searching unit, so we need an array whose length matches the unit count. var closestTargetArray = new NativeArray <TargetingSystemUtils.EntityWithPosition>(searchersQuery.CalculateEntityCount(), Allocator.TempJob); var findTargetJob = new FindTargetJob { targetArray = targetArray, closestTargetArray = closestTargetArray, }; // This separation is necessary because command buffers can't be used in Burst compiled structs. // We pass a reference to the same closestTargetArray to this job too, with the intention to read from it. // This requires the sequencing of the jobs to be correct. var assignTargetJob = new AssignTargetJob { closestTargetArray = closestTargetArray, commandBuffer = endSimCommandBufferSystem.CreateCommandBuffer().ToConcurrent(), }; // This makes the "find target" job a prerequisite for the "assign target" job, to ensure the closestTargetArray is initiated. var jobHandle = findTargetJob.Schedule(this, inputDeps); jobHandle = assignTargetJob.Schedule(this, jobHandle); endSimCommandBufferSystem.AddJobHandleForProducer(jobHandle); return(jobHandle); }
protected override JobHandle OnUpdate(JobHandle handle) { // filter by SharedComponentData // We can also filter using a componentData for each team var redRenderMesh = EntityManager.GetSharedComponentData <RenderMesh>(GetSingleton <BattleConfigData>().prefabRed); var blueRenderMesh = EntityManager.GetSharedComponentData <RenderMesh>(GetSingleton <BattleConfigData>().prefabBlue); // get red soldiers m_AllSoldiers.SetFilter(redRenderMesh); NativeArray <Entity> redSoldierEntities = m_AllSoldiers.ToEntityArray(Allocator.TempJob); // get blue soldiers m_AllSoldiers.SetFilter(blueRenderMesh); NativeArray <Entity> blueSoldierEntities = m_AllSoldiers.ToEntityArray(Allocator.TempJob); //CONFIGURE RED SOLDIERS // Schedule Job only on the Group of m_SoldiersWithoutTarget // Red soldiers without target var random = new Unity.Mathematics.Random((uint)UnityEngine.Random.Range(1, 100000)); // using the simple random for this example //https://forum.unity.com/threads/mathematics-random-with-in-ijobprocesscomponentdata.598192/ if (blueSoldierEntities.Length > 0) { m_SoldiersWithoutTarget.SetFilter(redRenderMesh); // red soldiers without target handle = new AssignTargetJob { // when to use ToConcurrent ? commandBuffer = endSimCommandBuffer.CreateCommandBuffer().ToConcurrent(), potentialTargets = blueSoldierEntities, random = random //}.ScheduleGroup(m_SoldiersWithoutTarget, handle); }.Schedule(m_SoldiersWithoutTarget, handle); endSimCommandBuffer.AddJobHandleForProducer(handle); } else { blueSoldierEntities.Dispose(); } //CONFIGURE BLUE SOLDIERS if (redSoldierEntities.Length > 0) { m_SoldiersWithoutTarget.SetFilter(blueRenderMesh); // blue soldiers without target handle = new AssignTargetJob { commandBuffer = endSimCommandBuffer.CreateCommandBuffer().ToConcurrent(), potentialTargets = redSoldierEntities, random = random //}.ScheduleGroup(m_SoldiersWithoutTarget, handle); }.Schedule(m_SoldiersWithoutTarget, handle); endSimCommandBuffer.AddJobHandleForProducer(handle); } else { redSoldierEntities.Dispose(); } // dispose return(handle); }