Search Unity

Question Line of Sight: only see what's in a cone in front of the player

Discussion in 'Editor & General Support' started by gsheidner, Apr 13, 2021.

  1. gsheidner

    gsheidner

    Joined:
    Sep 19, 2019
    Posts:
    3
    Hi, I'm fairly new to Unity. I'm trying to implement a feature in my 3D orthographic camera minigame so that the character would only be able to see an enemy or another character if they are in their line of sight (e.g., not behind the character, not behind a wall, within sight range). I've found a tutorial for something similar, made for enemies to detect the player if within line of sight. However, the script for the enemy uses the assignment of a "Target". I've implemented the same FOV script to the player and managed to enable the mesh renderer on the enemy when it's spotted, but I'm having a hard time doing two things: (1) making the script check all visible objects with the "Enemy" layer, and (2) disabling the mesh renderer on the enemy when not in the FOV anymore.

    Would a kind soul be willing to give detailed instructions, perhaps code snippets on how to solve this? The codes are below.

    Field of View Code:

    Code (CSharp):
    1. public class PlayerFOV : MonoBehaviour
    2. {
    3.     public Transform Target;
    4.     public float maxAngle;
    5.     public float maxRadius;
    6.     private bool isInFov = false;
    7.  
    8.     private void OnDrawGizmos()
    9.     {
    10.         Gizmos.color = Color.yellow;
    11.         Gizmos.DrawWireSphere(transform.position, maxRadius);
    12.  
    13.         Vector3 fovLine1 = Quaternion.AngleAxis(maxAngle, transform.up) * transform.forward * maxRadius;
    14.         Vector3 fovLine2 = Quaternion.AngleAxis(-maxAngle, transform.up) * transform.forward * maxRadius;
    15.  
    16.         Gizmos.color = Color.blue;
    17.         Gizmos.DrawRay(transform.position, fovLine1);
    18.         Gizmos.DrawRay(transform.position, fovLine2);
    19.  
    20.         if (!isInFov)
    21.         {
    22.             Gizmos.color = Color.red;
    23.             NotAlert();
    24.         }
    25.         else
    26.         {
    27.             Gizmos.color = Color.green;
    28.             Alert();
    29.         }
    30.         Gizmos.DrawRay(transform.position, (Target.position - transform.position).normalized * maxRadius);
    31.         Gizmos.color = Color.black;
    32.         Gizmos.DrawRay(transform.position, transform.forward * maxRadius);
    33.     }
    34.  
    35.     public static bool inFOV(Transform checkingObject, Transform target, float maxAngle, float maxRadius)
    36.     {
    37.         Collider[] overlaps = new Collider[100];
    38.         int count = Physics.OverlapSphereNonAlloc(checkingObject.position, maxRadius, overlaps);
    39.  
    40.         for (int i = 0; i < count + 1; i++)
    41.         {
    42.             if (overlaps[i] != null)
    43.             {
    44.                 if (overlaps[i].transform == target)
    45.                 {
    46.                     Vector3 directionBetween = (target.position - checkingObject.position).normalized;
    47.                     directionBetween.y *= 0;
    48.  
    49.                     float angle = Vector3.Angle(checkingObject.forward, directionBetween);
    50.  
    51.                     if (angle <= maxAngle)
    52.                     {
    53.                         Ray ray = new Ray(checkingObject.position, target.position - checkingObject.position);
    54.                         RaycastHit hit;
    55.  
    56.                         if (Physics.Raycast(ray, out hit, maxRadius))
    57.                         {
    58.                             if (hit.transform == target)
    59.                             {
    60.                                 hit.transform.SendMessage("HitByRay");
    61.                                 return true;
    62.                             }
    63.                         }
    64.                     }
    65.                 }
    66.             }
    67.         }
    68.         return false;
    69.     }
    70.  
    71.     public void Alert()
    72.     {
    73.         Renderer rend = GetComponent<Renderer>();
    74.         rend.material.SetColor("_Color", Color.red);
    75.     }
    76.  
    77.     public void NotAlert()
    78.     {
    79.         Renderer rend = GetComponent<Renderer>();
    80.         rend.material.SetColor("_Color", Color.green);
    81.     }
    82.  
    83.     private void Update()
    84.     {
    85.         isInFov = inFOV(transform, Target, maxAngle, maxRadius);
    86.     }
    87. }
    IsSeen Code:

    Code (CSharp):
    1. public class IsSeen : MonoBehaviour
    2. {
    3.     void HitByRay()
    4.     {
    5.         GetComponent<MeshRenderer>().enabled = true;
    6.     }
    7. }
    8.