private Vector3 Hide(AIAgent hunter, List <AIObject> obstacles) { float DistToClosest = float.MaxValue; Vector3 BestHidingSpot = Vector3.zero; AIObject closest; for (int i = 0; i < obstacles.Count; ++i) { AIObject curOb = obstacles[i]; Vector3 hidingSpot = GetHidingPosition(curOb.VPos(), curOb.BRadius(), hunter.VPos()); float dist = (m_entity.VPos() - hidingSpot).sqrMagnitude; DistToClosest = dist; BestHidingSpot = hidingSpot; if (dist < DistToClosest) { closest = curOb; } } //if no suitable obstacles found then Evade the hunter if (DistToClosest == float.MaxValue) { return(Evade(hunter)); } //else use Arrive on the hiding spot return(Arrive(BestHidingSpot, Deceleration.fast)); }
public void TagObstaclesWithinViewRange(AIAgent entity, float radius) { IEnumerator <AIObject> it = m_Obstacles.GetEnumerator(); while (it.MoveNext()) { AIObject curEntity = it.Current; //first clear any current tag curEntity.UnTagging(); Vector3 to = curEntity.VPos() - entity.VPos(); //the bounding radius of the other is taken into account by adding it //to the range float range = radius + curEntity.BRadius(); //if entity within range, tag for further consideration. (working in //distance-squared space to avoid sqrts) if ((curEntity.GetHashCode() != entity.GetHashCode()) && (to.sqrMagnitude < range * range)) { curEntity.Tagging(); } } }
public bool Overlapped(AIObject ob, List <AIObject> conOb, float MinDistBetweenObstacles) { IEnumerator <AIObject> it = conOb.GetEnumerator(); while (it.MoveNext()) { AIObject tmp = it.Current; if (MathUtil.TwoCirclesOverlapped(ob.VPos(), ob.BRadius() + MinDistBetweenObstacles, tmp.VPos(), tmp.BRadius())) { return(true); } } return(false); }
public void SetCrosshair(Vector3 p, string id = "basic") { Vector3 ProposedPosition = p; //make sure it's not inside an obstacle for (int i = 0; i < m_Obstacles.Count; ++i) { AIObject curOb = m_Obstacles[i]; if (MathUtil.PointInCircle(curOb.VPos(), curOb.BRadius(), ProposedPosition)) { return; } } AIGroup aiGroup = GetAIGroup(id); if (aiGroup != null) { aiGroup.SetCrosshair(p); } }
/** * Given a vector of obstacles, this method returns a steering force * that will prevent the agent colliding with the closest obstacle */ private Vector3 ObstacleAvoidance(List <AIObject> obstacles) { //* //the detection box length is proportional to the agent's velocity m_fDBoxLength = minDetectionBoxLength + (m_entity.Speed() / m_entity.MaxSpeed()) * minDetectionBoxLength; //tag all obstacles within range of the box for processing m_entity.World().TagObstaclesWithinViewRange(m_entity, m_fDBoxLength); //this will keep track of the closest intersecting obstacle (CIB) AIObject ClosestIntersectingObstacle = null; //this will be used to track the distance to the CIB float DistToClosestIP = float.MaxValue; //this will record the transformed local coordinates of the CIB Vector3 LocalPosOfClosestObstacle = Vector3.zero; IEnumerator <AIObject> it = obstacles.GetEnumerator(); for (int i = 0; i < obstacles.Count; ++i) { //if the obstacle has been tagged within range proceed AIObject curOb = obstacles[i]; if (curOb.Tag) { //calculate this obstacle's position in local space Vector3 LocalPos = MathUtil.PointToLocalSpace(curOb.VPos(), m_entity.Heading(), m_entity.Side(), m_entity.VPos()); // entity Heading and LocalPos is if (Vector3.Dot(LocalPos, Vector3.forward) > 0) { //than its radius + half the width of the detection box then there //is a potential intersection. float ExpandedRadius = curOb.BRadius() + m_entity.BRadius(); if (Mathf.Abs(LocalPos.x) < ExpandedRadius) { //test to see if this is the closest so far. If it is keep a //record of the obstacle and its local coordinates if (LocalPos.magnitude < DistToClosestIP) { DistToClosestIP = LocalPos.magnitude; ClosestIntersectingObstacle = curOb; LocalPosOfClosestObstacle = LocalPos; } } } } } //if we have found an intersecting obstacle, calculate a steering //force away from it Vector3 steeringForce = Vector3.zero; if (ClosestIntersectingObstacle != null) { //should be //the closer the agent is to an object, the stronger the //steering force should be float multiplier = 1.0f + (m_fDBoxLength - LocalPosOfClosestObstacle.z) / m_fDBoxLength; //calculate the lateral force steeringForce.x = (ClosestIntersectingObstacle.BRadius() - LocalPosOfClosestObstacle.x) * multiplier; //apply a braking force proportional to the obstacles distance from //the vehicle. float BrakingWeight = 0.2f; steeringForce.z = (ClosestIntersectingObstacle.BRadius() - LocalPosOfClosestObstacle.z) * BrakingWeight; } //finally, convert the steering vector from local to world space return(MathUtil.VectorToWorldSpace(steeringForce, m_entity.Heading(), m_entity.Side())); }