Untitled

 avatar
unknown
plain_text
3 months ago
3.8 kB
2
Indexable

    [BurstCompile]
    [WithPresent(typeof(AnimalStateEatFood))]
    [WithDisabled(typeof(OnStateExit), typeof(OnStateEnter))]
    partial struct FindFoodJob : IJobEntity
    {
        [ReadOnly] public NativeArray<LocalTransform> foodTransforms;
        [ReadOnly] public NativeArray<Entity> foodEntities;

        [NativeDisableParallelForRestriction]
        public NativeArray<Food> foodComponents;

        [NativeDisableContainerSafetyRestriction]
        public NativeList<int> foodTakenList;

        [NativeDisableContainerSafetyRestriction]
        public NativeArray<Unity.Mathematics.Random> randoms;
        [NativeSetThreadIndex] private int _threadId;

        [ReadOnly] public NavMeshQuery query;
        public float deltaTime;

        void Execute(Entity entity, ref LocalTransform transform, in Sensor sensor, ref AnimalStateFindFood findFood, ref NavAgentComponent agent
            , ref AnimalStateEatFood stateEatFood, in AnimalStateTypes states, ref OnStateExit stateExit, EnabledRefRW<OnStateExit> stateExitEnabled
            , [EntityIndexInQuery] int entityIndex)
        {
            if (findFood.FoodTarget == Entity.Null)
            {
                findFood.searchTime += deltaTime;
                int closestIndex = -1;
                float closestDistance = Mathf.Infinity;
                for (int i = 0; i < foodComponents.Length; i++)
                {
                    Entity foodEntity = foodEntities[i];
                    float dst = math.distancesq(transform.Position, foodTransforms[i].Position);
                    if (dst <= sensor.detectionDistance && dst < closestDistance && foodComponents[i].targetedBy == Entity.Null)
                    {
                        closestDistance = dst;
                        closestIndex = i;
                    }
                }

                if (closestIndex >= 0)
                {
                    var exchangeResult = Interlocked.CompareExchange(ref foodTakenList.ElementAt(closestIndex), entityIndex, 0);
                    if (exchangeResult == entityIndex)
                    {
                        Food food = foodComponents[closestIndex];
                        Entity closest = foodEntities[closestIndex];

                        findFood.searchTime = 0;
                        agent.targetEntity = closest;
                        findFood.FoodTarget = closest;


                        food.targetedBy = entity;
                        foodComponents[closestIndex] = food;
                    }
                }
                else if (!agent.useTargetPosition)
                {
                    float3 extents = new float3(0.5f, 1, 0.5f);
                    var rnd = randoms[_threadId];
                    float3 rndOffset = rnd.NextFloat3(new float3(-5, 0, -5), new float3(5, 0, 5));
                    randoms[_threadId] = rnd;

                    float3 dst = transform.Position + rndOffset;
                    NavMeshLocation fromLocation = query.MapLocation(dst, extents, 0);
                    NavMeshHit hit;
                    var res = query.Raycast(out hit, fromLocation, dst - new float3(0, 100, 0));
                    if (res == PathQueryStatus.Success)
                    {
                        agent.useTargetPosition = true;
                        agent.targetPosition = dst;

                    }
                }
            }
            else
            {
                if (agent.targetEntity == Entity.Null)
                {
                    stateEatFood.FoodTarget = findFood.FoodTarget;
                    findFood.FoodTarget = Entity.Null;
                    TransitionStateExitSystem.SwitchState(ref stateExit, ref stateExitEnabled, in states.eatFood);
                }
            }
        }
    }
}
Editor is loading...
Leave a Comment