Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Visual debugging a Field of view angle

Discussion in 'Scripting' started by Antao98, Feb 13, 2018.

  1. Antao98

    Antao98

    Joined:
    Jun 26, 2017
    Posts:
    5
    I've been trying for the past few days trying to figure out a way to visual debug a field of view angle.
    I've tried it multiple ways with a custom editor and a mesh but its too confusing for me. Is there a simpler way to do this?
    I have this field of view script for enemies to see the player. Everything works fine, but I could really use the debug to figure out view ranges.

    I'll post the code below.

    Code (CSharp):
    1. void Update () {
    2.  
    3.         inCell = player.GetComponent<PlayerMovement> ().playerInCell;
    4.  
    5.         if(inCell == true)
    6.         {
    7.             Patrol ();
    8.         }
    9.         else
    10.         {
    11.             CheckForLights ();
    12.             FieldOfView ();
    13.             //Debug.Log ("A luz da cena está: " + sceneLightStatus + " e o player tem a luz: " + playerLightStatus);
    14.  
    15.             if(playerInSight == true && playerInRange == true)
    16.             {
    17.                 inPursuit = true;
    18.                 agent.SetDestination (target.transform.position);
    19.             }
    20.             else
    21.             {
    22.                 Patrol ();
    23.             }
    24.         }
    25.     }
    26.  
    27.     void FixedUpdate()
    28.     {
    29.         Vector3 raycastDirection = target.transform.position - transform.position;
    30.  
    31.         RaycastHit hit;
    32.  
    33.         if(Physics.Raycast (transform.position, raycastDirection, out hit, viewDistance) && hit.transform.tag == "Player")
    34.         {
    35.             playerInRange = true;
    36.         }
    37.         else{
    38.             Invoke ("ChangePlayerInRange", exitTime);
    39.         }
    40.     }
    41.  
    42.     void FieldOfView()
    43.     {
    44.         Vector3 targetDir = target.position - transform.position;
    45.         float angle = Vector3.Angle (targetDir, transform.forward);
    46.  
    47.         minimumDistance = Vector3.Distance (target.transform.position, transform.position);
    48.  
    49.         if(angle < FOV * 0.5f && minimumDistance > 2f)
    50.         {
    51.             playerInSight = true;
    52.         }
    53.         else if(minimumDistance < 2f){
    54.             playerBusted = true;
    55.             playerInSight = true;
    56.         }
    57.         else{
    58.             Invoke ("ChangePlayerInSight", exitTime);
    59.             //playerInSight = false;
    60.         }
    61.     }
     
    Last edited: Feb 13, 2018
  2. solidearthvr

    solidearthvr

    Joined:
    Jan 23, 2017
    Posts:
    50
  3. Antao98

    Antao98

    Joined:
    Jun 26, 2017
    Posts:
    5
    I could try drawing 3 rays, one for each direction, like this:
    https://imgur.com/fioIBi8

    Edit:
    Been thinking, to achieve this I will need 3 points to make a proper angle. Everytime I change the angle of the FOV, I will have to change these values manually
     
    Last edited: Feb 13, 2018
  4. DonLoquacious

    DonLoquacious

    Joined:
    Feb 24, 2013
    Posts:
    1,667
    Yep, calculate the extents and then Debug.DrawRay. If you're debugging a field of view for 2D, then it's three lines, but if you're doing in 3D then it's actually 8. Look at the way the camera's field of view is drawn in the scene view for a good guide- it's just 4 points calculated as extents from an origin point, so 5 points in space- draw lines between them and it should look fine.

    The math shouldn't be very hard- if there's a transform at the origin point, then you can use Transform.TransformPoint to calculate the positions easily, and if not then you can use something like this to do the same thing:
    Code (CSharp):
    1. public Vector3 RotatePointAroundPivot(Vector3 point, Vector3 pivot, Vector3 eulerRotation)
    2. {
    3.     return Quaternion.Euler(eulerRotation) * (point - pivot) + pivot;
    4. }
    Just keep in mind that the "direction" or "dir" parameter for the Debug.DrawLine function determines the length of the line, using the magnitude (IIRC).
     
  5. Antao98

    Antao98

    Joined:
    Jun 26, 2017
    Posts:
    5
  6. DonLoquacious

    DonLoquacious

    Joined:
    Feb 24, 2013
    Posts:
    1,667
    Yeah, creating a mesh feels like overkill to me, especially if it's only something you're using as a visual indicator rather than a runtime asset. I suggest looking into Handles if you want a more robust way of dealing with this kind of thing. That also felt like overkill for the current scenario, but it's a fantastic way of drawing both selectable controls and visual aids for the editor.
     
  7. Antao98

    Antao98

    Joined:
    Jun 26, 2017
    Posts:
    5
    I checked out Handles, but I found it so confusing because of the editor script. I think i'll use the mesh generation