Example #1
0
    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);
    }