What's a good way to debug line of sight code properly?

So I’m following this tutorial on line of sight and I get the general idea however things have been a bit hit and miss with me getting it working, I’m doing a simple version of the code in this tutorial with no animator or anything and I am just doing a patrolling capsule with line of sight detection. The capsule when detecting the player should turn red, I managed to get it working a little bit but unfortunately it’s just too tricky for me right now without good debugging to see whether or not the raycasting is even working.

I tried putting up some debug logging to at least let me know when the player is even being detected or not and I wanted to draw the raycast using debug as you normally would, however it threw up an error, does anyone know what the proper way of having line of sight show up in your scene as a debug line or something so you can see if it’s being drawn correctly?

Here’s the code I have, it may well be that I have something wrong here and there as well that means the code isn’t connecting the collider to everything properly so that’s why the detection isn’t working so well but I can’t know that if I can’t even see the raycast.

using UnityEngine;
using System.Collections;

public class Patrol : MonoBehaviour {

    public Transform [] points;
    private int destPoint = 0;
    private NavMeshAgent agent;
    public float FieldOfViewAngle = 110f;
    public bool PlayerInSight;
    public SphereCollider col;
    private GameObject player;


    void Awake ()

    {
        col = GetComponent<SphereCollider> ();
        player = GameObject.FindGameObjectWithTag ("Player");
    }

    // Use this for initialization
    void Start () {

        agent = GetComponent <NavMeshAgent> ();

        GoToNextPoint ();
 
    }

    void GoToNextPoint ()

    {
        if (points.Length == 0)

            return;


        agent.destination = points [destPoint].position;

        destPoint = (destPoint + 1) % points.Length;
    }
 
    // Update is called once per frame
    void Update () {

        if (agent.remainingDistance < 0.1f)
     
        {
            GoToNextPoint ();
        }
 
    }

    void OnTriggerStay ( Collider other )
    {

        if (other.gameObject == player)
     
        {
            PlayerInSight = false;

            Vector3 direction = other.transform.position - transform.position;
            float angle = Vector3.Angle (direction, transform.forward);

            if (angle < FieldOfViewAngle * 0.5f)
         
            {
                RaycastHit hit;

                if (Physics.Raycast (transform.position + transform.up, direction.normalized, out hit, col.radius))
                    Debug.Log ("Raycast Drawn");

                    {


                    if ( hit.collider.gameObject == player )
                 
                    {
                        PlayerInSight = true;
                        gameObject.GetComponent<Renderer>().material.color = Color.red;
                        Debug.Log ("Player Detected");
                    }

                    }

            }

        }

    }


}

I noticed that as well despite me being able to change the colour of the capsule at times the boolean itself wouldn’t change and the debug log wouldn’t give me “Player detected” to indicate everything is working, so I wonder what that’s all about. What’s interesting is that the patrolling code works fine and the agent goes to the designated points without any bother, so it must be something to do with the code inside OnTriggerStay.

Debug.DrawRay

always good to see whats what

Ahhh didn’t know you could have Ray Gizmo’s too, thanks, I’ll check it out.

there’s also a bunch of scene view rendering stuff in

but that’s more for editor tooling rather than on the fly debugging

Hmmmm -_- feel like I’m being a total noob, I don’t use Gizmos very often.

    void OnDrawGizmosSelected ( Collider other )

    {
        Gizmos.color = Color.red;

        Vector3 direction = other.transform.position - transform.position;
        float angle = Vector3.Angle (direction, transform.forward);
        RaycastHit hit
        Gizmos.DrawRay ( transform.position + transform.up, direction.normalized, out hit, col.radius );


    }

Looks like you’ve just copy-pasted the raycast call, the Gizmos.DrawRay method has different parameters. Either a Ray or a set with position and direction vectors, so basically just remove out hit and col.radius.[/QUOTE]

Won’t that mean though that I’m just pointlessly generating a debug ray that’s not in line with the line of sight code that I’m using? I was hoping I could get the debug rays to work for the raycast I’m making so I could see and adjust the line of sight more precisely and so on.

you can, but you’ll need a public class variable so you can set the ray in the trigger function and use the same ray in the gizmos function.

My LoS code uses Handles.DrawSolidArc to show agents’ visibility ranges for on the fly debugging in the editor. It’s really handy.

2 Likes

Now that looks far more solid that function because it takes into account the radius so I should be able to put the collider in that right? I’ll have a closer look at that, thanks.

Okay guys, I figured out what was going on and the culprit was this little line of code here, ended up figuring it out without the DrawSolidArc function.

if (Physics.Raycast (transform.position + transform.up, direction.normalized, out hit, col.radius))

I simply got rid of the transform.up command.

if (Physics.Raycast (transform.position, direction.normalized, out hit, col.radius))

Now I think this might be because that bit of code was unnecessary but I remembered this from investigating how raycasts worked in general when I was looking at building placement. In the video the developer claimed that the ray would project from the feet, but that’s not true anymore. It projects automatically directly from the pivot point and in this case it was already at the centre so making the ray go up by two units actually meant it was way above the enemy capsule I had and that explains why I could trigger it by jumping on it’s head.

I’ve run into a new problem now though and that’s for some reason, there are times when it works absolutely perfectly, the material component turns red when I enter the line of sight ( I can even sneak behind him and he won’t notice me which is awesome ) however there are other times when the enemy glitches out and stays permanently red even after I leave the collider which shouldn’t happen.

Does anyone have any ideas as to what’s causing that? I just did some reading and I was wondering if people are right in that it’s because the trigger is not checking every frame for the player, when you look at the code that makes perfect sense though, so I’ll give it a try.