/* Performs a 180 degree sweep of multiple raycasts in front of the zombie, * returning an array of RaycastSweepHit objects */ RaycastSweepHit[] RaycastSweep180(int numCasts = 9) { List <RaycastSweepHit> hits = new List <RaycastSweepHit>(); // Number of degrees to increment rotation by after each cast float degreesIncrement = 180f / (float)numCasts; // Temporarily disable boxcollider so we don't hit ourselves with the raycast boxCollider.enabled = false; // Do a 180 degree sweep of raycasts for (float angleOffset = 0f; angleOffset <= 180f; angleOffset += degreesIncrement) { // Calculate direction for this raycast Vector3 castDir = Quaternion.Euler(0, 0, angleOffset) * (-transform.up); // Do the raycast RaycastSweepHit hit = new RaycastSweepHit(Physics2D.Raycast(gameObject.transform.position, castDir), angleOffset); hits.Add(hit); // Draw a line showing the raycast, uncomment for debugging Debug.DrawLine(gameObject.transform.position, hit.hit.point, Color.green); } // Re-enable boxcollider boxCollider.enabled = true; // Convert results to array and return return(hits.ToArray()); }
/* Processes an array of RaycastSweepHit objects into a single ProcessedRaycastSweep * object containing only the information needed to determine next actions. */ ProcessedRaycastSweep ProcessRaycastSweep(RaycastSweepHit[] hits) { // Highest cast distance we've seen so far float highestDistance = 0.0f; // Rotation angle offset corresponding with highest cast distance float highestAngle = 0.0f; // Shortes cast distance we've seen so far float shortestDistance = float.MaxValue; // Rotation angle offset corresponding with highest cast distance float shortestAngle = 0.0f; // Nearest follow-able zombie RaycastSweepHit nearestZombieHit = null; GameObject nearestZombie = null; // Nearest follow-able zombie script Zombie nearestZombieScript = null; // nearest destructible object RaycastSweepHit nearestDestructibleHit = null; GameObject nearestDestructible = null; foreach (RaycastSweepHit hit in hits) { // Did we hit a zombie? if ("Zombie" == hit.hit.transform.gameObject.tag) { // Is it in a state that means it is following the player? Zombie otherZombie = hit.hit.transform.gameObject.GetComponent <Zombie>(); if (nearestZombieHit == null || (hit.hit.distance < nearestZombieHit.hit.distance)) { if (isWorthFollowing(otherZombie)) { nearestZombieHit = hit; nearestZombie = hit.hit.transform.gameObject; } } } // Did we hit a destructible wall? else if (hit.hit.transform.parent != null) { if (hit.hit.transform.parent.gameObject.tag == "DestructibleBlock") { if ((nearestDestructibleHit == null) || (hit.hit.distance < nearestDestructibleHit.hit.distance)) { nearestDestructibleHit = hit; nearestDestructible = hit.hit.transform.gameObject; } } } // Keep track of shortest and longest raycast distance if (hit.hit.distance > highestDistance) { highestDistance = hit.hit.distance; highestAngle = hit.angle; } if (hit.hit.distance < shortestDistance) { shortestDistance = hit.hit.distance; shortestAngle = hit.angle; } } if (nearestZombie != null) { nearestZombieScript = nearestZombie.GetComponent <Zombie>(); } return(new ProcessedRaycastSweep(nearestZombie, nearestZombieScript, nearestDestructible, highestAngle, shortestAngle)); }