protected float GetWeight(Vector2 position, Vector2 destination, float areaEffectDistance, float totalInfluenceDistance, bool linear)
    {
        float sqrDistance               = Vector2Utilities.SqrDistance(position, destination);
        float sqrAreaEfectDistance      = Mathf.Pow(areaEffectDistance, 2);
        float sqrTotalInfluenceDistance = Mathf.Pow(totalInfluenceDistance, 2);

        if (sqrAreaEfectDistance < sqrDistance)
        {
            return(0);
        }
        else if (sqrDistance <= sqrTotalInfluenceDistance)
        {
            return(1);
        }


        float weight;

        if (linear)
        {
            weight = 1 - ((Mathf.Sqrt(sqrDistance) - totalInfluenceDistance) / (areaEffectDistance - totalInfluenceDistance));
        }
        else
        {
            weight = 1 - (sqrDistance - sqrTotalInfluenceDistance) / (sqrAreaEfectDistance - sqrTotalInfluenceDistance);
        }


        return(weight);
    }
Пример #2
0
    public Vector2 GetDesiredDestination(AIAgent requester)
    {
        Vector2     position      = requester.transform.position;
        AIAgentData requesterData = requester.data;
        ITargetable target        = requester.Target;

        if (target == null)
        {
            //Debug.LogError($"{requester} has no posible targets");
            return(requester.parent.GetCohesionPosition(requester));
        }

        Vector2 targetPos = target.GameObject.transform.position;
        Vector2 directionTowardsPosition = (position - targetPos).normalized;

        float requesterRadiousOffset = requesterData.shape == Shape.CIRCULAR ? requesterData.radious :
                                       Vector2Utilities.GetDistanceOfSquareEdgeAndCenterFromDirection(requesterData.radious, directionTowardsPosition);

        float targetRadiousOffset = target.BodyShape == Shape.CIRCULAR ? target.Radious :
                                    Vector2Utilities.GetDistanceOfSquareEdgeAndCenterFromDirection(target.Radious, directionTowardsPosition);

        Vector2 destinationPoint = targetPos + directionTowardsPosition * (requesterRadiousOffset + targetRadiousOffset);

        return(destinationPoint);
    }
    public static Vector2?ObstacleAvoidance(AIAgent requester, Vector2 position, Vector2 desiredDirection, out AIAgent avoidanceObjective)
    {
        if (requester.parent.ClosestUnit == null)
        {
            avoidanceObjective = null;
            return(null);
        }

        float objectiveSqrDistance;

        if (requester.Target is AIAgent)
        {
            if (!GetClosestAgent(requester, position, requester.parent.ClosestUnit.children,
                                 out avoidanceObjective, out objectiveSqrDistance, (AIAgent)requester.Target))
            {
                return(null);
            }
        }
        else
        {
            if (!GetClosestAgent(requester, position, requester.parent.ClosestUnit.children,
                                 out avoidanceObjective, out objectiveSqrDistance))
            {
                return(null);
            }
        }
        Vector2 objectiveDirection = ((Vector2)avoidanceObjective.transform.position - position).normalized;

        Vector2 perpendicular = Vector2Utilities.VectorPerpendicularToDesired(desiredDirection, objectiveDirection);

        return(position + perpendicular * requester.data.maxSpeed * Time.deltaTime);
    }
    public static Vector2?Separation(AIAgent requester, Vector2 position, Vector2 desiredDirection, out AIAgent closestSiblin, out Vector2 directionToClosestSiblin)
    {
        List <AIAgent> siblins = requester.parent.children;

        float closestSiblinSqrDistance;

        if (!GetClosestAgent(requester, position, siblins, out closestSiblin, out closestSiblinSqrDistance))
        {
            closestSiblin            = null;
            directionToClosestSiblin = Vector2.zero;
            return(null);
        }


        float repulsionMaxSqrRange = Mathf.Pow(requester.data.radious * requester.data.separationRangeInRadious, 2);

        directionToClosestSiblin = ((Vector2)closestSiblin.transform.position - position).normalized;

        if (repulsionMaxSqrRange < closestSiblinSqrDistance)
        {
            return(null);
        }

        Vector2 perpendicular = Vector2Utilities.VectorPerpendicularToDesired(desiredDirection, directionToClosestSiblin);

        return(position + perpendicular * requester.data.maxSpeed * Time.deltaTime);
    }
    public static bool GetClosestAgent(AIAgent requester, Vector2 requesterPosition, List <AIAgent> options, out AIAgent closestSiblin, out float closestSiblinSqrDistance, AIAgent exception = null)
    {
        bool areClosestAgent = false;

        closestSiblin            = null;
        closestSiblinSqrDistance = float.MaxValue;
        for (int i = 0; i < options.Count; i++)
        {
            AIAgent tempAgent = options[i];

            if (tempAgent == requester || tempAgent == exception)
            {
                continue;
            }

            float tempSqrDistance = Vector2Utilities.SqrDistance(requesterPosition, tempAgent.transform.position);
            if (tempSqrDistance < closestSiblinSqrDistance)
            {
                areClosestAgent          = true;
                closestSiblin            = tempAgent;
                closestSiblinSqrDistance = tempSqrDistance;
            }
        }
        return(areClosestAgent);
    }
Пример #6
0
    private List <ITargetable> GetPrioritizedTargets(List <ITargetable> filteredPosibleTargets, Vector2 position)
    {
        bool haveAgent = false;

        ITargetable closestPosibleTarget    = null;//estructuras?
        float       closestStructureSqrDist = float.MaxValue;
        AIAgent     closestAgent            = null;
        float       closestAgentSqrDist     = float.MaxValue;

        foreach (ITargetable targetable in filteredPosibleTargets)
        {
            Vector2 targetPos = targetable.GameObject.transform.position;
            if (targetable is AIAgent)
            {
                haveAgent = true;
                float sqrDist = Vector2Utilities.SqrDistance(targetPos, position);
                if (sqrDist < closestAgentSqrDist)
                {
                    closestAgent        = (AIAgent)targetable;
                    closestAgentSqrDist = sqrDist;
                }
            }
            else
            {
                if (haveAgent)
                {
                    continue;
                }

                float sqrDist = Vector2Utilities.SqrDistance(targetPos, position);
                if (sqrDist < closestStructureSqrDist)
                {
                    closestPosibleTarget    = targetable;
                    closestStructureSqrDist = sqrDist;
                }
            }
        }

        List <ITargetable> returnTargets = new List <ITargetable>();

        if (haveAgent)
        {
            returnTargets = closestAgent.parent.children.ConvertAll(x => (ITargetable)x);
            return(returnTargets);
        }
        else if (closestPosibleTarget != null)
        {
            returnTargets.Add(closestPosibleTarget);
            return(returnTargets);
        }
        else
        {
            return(null);
        }
    }
Пример #7
0
    public IBehaviourSet GetBehaviourSet(AIAgent requester)
    {
        Vector2 pos = requester.transform.position;
        Vector2 des = requester.Destination;

        if (ObstacleToDestination(pos, des, requester.data.radious, raycastMask))
        {
            return(interferenceBS);
        }

        float sqrDist = Vector2Utilities.SqrDistance(pos, des);

        if (sqrDist <= Mathf.Pow(requester.action.BaseData.rangeOfAction + requester.data.reachDestinationMargin, 2))
        {
            return(actingBS);
        }

        return(defaultBS);
    }
    public IBehaviourSet GetBehaviourSet(AIAgent requester)
    {
        Vector2 pos = requester.transform.position;
        Vector2 des = requester.Destination;

        if (ObstacleToDestination(pos, des, requester.data.radious, raycastMask))
        {
            return(interferenceBS);
        }
        else if (Vector2Utilities.SqrDistance(pos, des) <= Mathf.Pow(requester.data.idleBSRange, 2) && !requester.parent.Moving)
        {
            if (requester.debug)
            {
                Debug.Log($"returning parkingBS");
            }
            return(idleBS);
        }

        return(defaultBS);
    }
Пример #9
0
    public bool UseStuckBehaviour(out Vector2?stuckDestination)
    {
        if (currentlyUsingSB)
        {
            if (!Moving)
            {
                stuckDestination = currentStuckDestination = CalculateStuckDestination(parent.Data.obstacleLayerMask);
            }


            float sqrDistToStuckDest = Vector2Utilities.SqrDistance((Vector2)transform.position, currentStuckDestination);
            if (sqrDistToStuckDest < Mathf.Pow(data.reachDestinationMargin, 2) || InActionRangeToDestination)
            {
                stuckDestination = null;
                currentlyUsingSB = false;
                return(false);
            }
            else
            {
                stuckDestination = currentStuckDestination;
                return(true);
            }
            //debo revisar si es que se vuelva a atrapar luego de ya estar atrapado.
        }
        else
        {
            if (!Moving && !InActionRangeToDestination && !BSJustChanged)
            {
                stuckDestination = currentStuckDestination = CalculateStuckDestination(parent.Data.obstacleLayerMask);
                currentlyUsingSB = true;
                ResetMovementDelta();
                return(true);
            }
            else
            {
                stuckDestination = null;
                currentlyUsingSB = false;
                return(false);
            }
        }
    }
    public static Vector2 Arribe(AIAgent requester, Vector2 position, Vector2 destinationPoint, float deltaTime, bool decelerate = true, bool useStopRadious = true)
    {
        AIAgentData requesterData = requester.data;

        float sqrDist = Vector2Utilities.SqrDistance(destinationPoint, position);

        //in stop radious
        if (sqrDist <= Mathf.Pow(requesterData.stopRadious, 2) && useStopRadious)
        {
            return(position);
        }
        //in slow down radious
        else if (sqrDist < Mathf.Pow(requesterData.slowDownStartRadious, 2) && decelerate)
        {
            Vector2 direction = (destinationPoint - position).normalized;

            float dist              = Mathf.Sqrt(sqrDist);
            float speedMult         = dist / requesterData.slowDownStartRadious;
            float movementMagnitude = requesterData.maxSpeed * speedMult * deltaTime;
            //prevent overshooting
            if (dist <= movementMagnitude)
            {
                return(destinationPoint);
            }
            return(position + direction * movementMagnitude);
        }
        else
        {
            float dist = Mathf.Sqrt(sqrDist);
            float movementMagnitude = requesterData.maxSpeed * deltaTime;
            if (dist <= movementMagnitude)
            {
                return(destinationPoint);
            }

            Vector2 direction = (destinationPoint - position) / dist;
            return(position + direction * movementMagnitude);
        }
    }