When dealing with military games, especially FPS, we need to define a waypoint value, by its capacity, to be a good cover point with the maximum visibility for shooting or reaching other enemies visually. This recipe helps us compute a waypoint's value given these parameters.
We need to create a function for checking whether a position is in the same room as others:
public bool IsInSameRoom(Vector3 from, Vector3 location, string tagWall = "Wall") { RaycastHit[] hits; Vector3 direction = location - from; float rayLength = direction.magnitude; direction.Normalize(); Ray ray = new Ray(from, direction); hits = Physics.RaycastAll(ray, rayLength); foreach (RaycastHit h in hits) { string tagObj = h.collider.gameObject.tag; if (tagObj.Equals(tagWall)) return false; } return true; }
We will create the function that computes the quality of the waypoint:
public static float GetCoverQuality( Vector3 location, int iterations, Vector3 characterSize, float radius, float randomRadius, float deltaAngle) { // next steps }
float theta = 0f; int hits = 0; int valid = 0;
for (int i = 0; i < iterations; i++) { // next steps } return (float)(hits / valid);
Vector3 from = location; float randomBinomial = Random.Range(-1f, 1f); from.x += radius * Mathf.Cos(theta) + randomBinomial * randomRadius; from.y += Random.value * 2f * randomRadius; from.z += radius * Mathf.Sin(theta) + randomBinomial * randomRadius;
if (!IsInSameRoom(from, location)) continue; valid++;
Vector3 to = location; to.x += Random.Range(-1f, 1f) * characterSize.x; to.y += Random.value * characterSize.y; to.z += Random.Range(-1f, 1f) * characterSize.z;
Vector3 direction = to - location; float distance = direction.magnitude; direction.Normalize(); Ray ray = new Ray(location, direction); if (Physics.Raycast(ray, distance)) hits++; theta = Mathf.Deg2Rad * deltaAngle;
3.147.47.166