/* * Here we're looking for the closest player to the Ai. * If we're already following a player, just make sure it's in our line of sight and return the current player * If something is in the way, look for another player * Cast a line to all players and if the line hits the player, see which player hit is closest to you * return the players position */ public static Transform Ai_FindPlayer(this Ai ai) { if (ai.Player) { if (ai.InRange(ai.Player.position, ai.visionDistance)) { if (Physics.Linecast(ai.transform.position, ai.Player.position, out hit, ~(ai.breadcrumbLayer | ai.waypointLayer))) { if (hit.collider.tag == playerString) { if (players != null) { foreach (GameObject p in players) { if (p == hit.collider.gameObject) { ai.Player = p.transform; return(ai.Player); } } } } else { ai.Player = null; } } } else { ai.Player = null; } } float distance = Mathf.Infinity; if (players != null) { foreach (GameObject p in players) { if (p && ai.InRange(p.transform.position, ai.visionDistance)) { if (Physics.Linecast(ai.transform.position, p.transform.position, out hit, ~(ai.breadcrumbLayer | ai.waypointLayer))) { if (hit.collider.tag == playerString) { Vector3 diff = p.transform.position - ai.transform.position; float curDistance = diff.sqrMagnitude; if (curDistance < distance) { ai.Player = p.transform; ai.FollowingPlayer = p.transform; distance = curDistance; } } } } } } return(ai.Player); }
/* * Here we're looking for Breadcrumbs that the player leaves behind. * First we see if we're already looking at a breadcrumb, if we are and we haven't reached it yet, return the breadcrumb * If we don't have a breadcrumb or something is blocking the current one (or it doesn't exist anymore) * then we look for a new one. The Ai looks for a breadcrumb that's visible and closest to the player. */ public static Transform Ai_FindBreadcrumb(this Ai ai) { if (ai.Breadcrumb) { if (ai.InRange(ai.Breadcrumb.position, ai.visionDistance)) { if (Physics.Linecast(ai.transform.position, ai.Breadcrumb.position, out hit, ~(ai.waypointLayer))) { if (hit.collider.tag == breadcrumbString) { if (Vector3.Distance(ai.transform.position, ai.Breadcrumb.position) > 0.5f) { return(ai.Breadcrumb); } else { ai.Breadcrumb = null; } } else { ai.Breadcrumb = null; } } } else { ai.Breadcrumb = null; } } float distance = Mathf.Infinity; if (breadcrumbs != null) { foreach (GameObject crumb in breadcrumbs) { if (crumb && ai.InRange(crumb.transform.position, ai.visionDistance)) { if (Physics.Linecast(ai.transform.position, crumb.transform.position, out hit, ~(ai.waypointLayer))) { if (hit.collider.tag == breadcrumbString) { Vector3 diff = crumb.transform.position - ai.FollowingPlayer.position; float curDistance = diff.sqrMagnitude; if (curDistance < distance) { ai.Breadcrumb = crumb.transform; distance = curDistance; } } } } } } return(ai.Breadcrumb); }
/* * Here we're looking for another Ai that is currently following a player. * If this Ai cannot see a player but it sees another Ai who is following the player (out of our line of sight) then return the Ai to follow * If the Ai is out of our line of sight or no longer sees a player then look for another Ai * We set a radius around us and find all Enemy Ai. We cast a line to their position. * If the ray hits something, then return null, if it doesn't hit anything, then find the closest Ai and return that Ai. */ public static Transform Ai_FindAi(this Ai ai) { if (ai.FollowingAi) { if (ai.InRange(ai.FollowingAi.position, ai.visionDistance)) { if (Physics.Linecast(ai.transform.position, ai.FollowingAi.position, out hit, ~(ai.breadcrumbLayer | ai.waypointLayer))) { if (hit.collider.tag == enemyString && hit.collider.gameObject.GetComponent <Ai>().visionState == Ai.VISION_STATE.CanSeePlayer || hit.collider.tag == enemyString && hit.collider.gameObject.GetComponent <Ai>().visionState == Ai.VISION_STATE.CanSeeBreadcrumb) { return(ai.FollowingAi); } else { ai.FollowingAi = null; } } else { ai.FollowingAi = null; } } else { ai.FollowingAi = null; } } else { float distance = Mathf.Infinity; float radius = ai.visionDistance / 2; if (!ai._HasVision) { radius = 10000; // If the Ai doesn't use vision, use a radius of 10000 } Collider[] colliders = Physics.OverlapSphere(ai.transform.position, radius, ai.enemyLayer); foreach (Collider collider in colliders) { if (collider.tag == enemyString && collider.gameObject.GetComponent <Ai>().visionState == Ai.VISION_STATE.CanSeePlayer || collider.tag == enemyString && collider.gameObject.GetComponent <Ai>().visionState == Ai.VISION_STATE.CanSeeBreadcrumb) { if (!Physics.Linecast(ai.transform.position, collider.transform.position, out hit, ~(ai.breadcrumbLayer | ai.waypointLayer | ai.enemyLayer))) { Vector3 dir = collider.transform.position - ai.transform.position; float dist = dir.sqrMagnitude; if (dist < distance) { ai.FollowingAi = collider.transform; distance = dist; } } } } } return(ai.FollowingAi); }