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);
    }