Search Unity

Raycast going through other objects

Discussion in 'Scripting' started by LionFische, Feb 12, 2016.

  1. LionFische

    LionFische

    Joined:
    Oct 16, 2015
    Posts:
    107
    Hi I am having a problem with Raycasting.

    I have a player character represented by a cube and a patrol represented by another cube. The patrol cycles through waypoints while the player is free to walk around.

    Attached to the Patrol cube I have another cube, set to act as a detection zone. When this zone is triggered, the patrol cube attempts to locate the player and fire a raycast at the player. This is being successfully achieved.

    However the issue is, I want the player to be able to then move and hide itself from the view of the patrol. So when the player has an object positioned between itself and the patrol, the raycast can not see the player.

    The code I am using according to the documents should not pass a ray through other objects with Colliders, however my code is doing just that.

    (I have tried a few variations, so some of these are still there and commented out).

    The Code

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class PatrolDetection : MonoBehaviour {
    5.  
    6.     public LayerMask sightBlockingLayers;
    7.  
    8.     public RaycastHit hit;
    9.  
    10.     public float maxRayCastRange = 500.0f;
    11.  
    12.     //general detection
    13.     public bool isDetected = false;
    14.     //can see target
    15.     public bool canSee = false;
    16.    
    17.     void OnTriggerStay(Collider other)
    18.     {
    19.         isDetected = true;
    20.         if (Physics.Raycast(transform.position, (other.transform.position - transform.position), out hit))
    21.         //if (Physics.Raycast(transform.position, (other.transform.position - transform.position), out hit, sightBlockingLayers))
    22.         //if(Physics.Raycast(transform.position, (other.transform.position - transform.position), out hit, 100, sightBlockingLayers))
    23.         //if(Physics.Raycast(origin: transform.position, direction: (other.transform.position - transform.position), hitInfo: out hit, layerMask: sightBlockingLayers))
    24.         //if(Physics.Raycast(transform.position, (other.transform.position - transform.position), out hit, maxRayCastRange, sightBlockingLayers))
    25.  
    26.         {
    27.             //if(hit.collider.gameObject.name == "Player")
    28.             if(other.gameObject.name == "Player")
    29.             {
    30.                 Debug.Log ("The " + other + " is staying in the collider");
    31.                 canSee = true;
    32.                 //Debug.Log ("I can see the " + other);              
    33.                 Debug.DrawLine (transform.parent.position, hit.point);
    34.             }
    35.         }
    36.     }
    37.  
    38.     /*void OnTriggerEnter(Collider other)
    39.     {
    40.  
    41.         if (Physics.Raycast(transform.position, (other.transform.position - transform.position), out hit))
    42.         {
    43.             if(other.gameObject.name == "Player")
    44.             {
    45.                 Debug.Log ("The " + other + " entered the collider");
    46.                 isDetected = true;
    47.                 //Debug.Log ("I can see the " + other);              
    48.                 Debug.DrawLine (transform.parent.position, hit.point);
    49.             }
    50.         }
    51.     }*/
    52.  
    53.     void OnTriggerExit(Collider other)
    54.     {
    55.         isDetected = false;
    56.         if(other.gameObject.CompareTag("Player"))
    57.         {
    58.             Debug.Log("The " + other + " exited the collider");
    59.             canSee = false;
    60.         }
    61.     }
    62. }
    63.  
    This has me stuck, any advice would be most appreciated!

    2h
     
  2. bigmisterb

    bigmisterb

    Joined:
    Nov 6, 2010
    Posts:
    4,221
    so... canSee is never set back to false unless the player leaves the trigger?
     
  3. Browdaddy96

    Browdaddy96

    Joined:
    Aug 27, 2015
    Posts:
    82
    You have to use RayCastHit and create an obstacle or a hidden layer and assisng it to a layerMask like :

    Code (CSharp):
    1. public LayerMask hiddenMask;//assign in Inspector
    2.  
    3. RayCastHit checkHidden;
    4.  
    5. //set what checkHidden hits
    6.  
    7. if(hit)
    8. {
    9.       canSee = false;
    10. }
    Should work, at school so I cant test it for you.
     
  4. LionFische

    LionFische

    Joined:
    Oct 16, 2015
    Posts:
    107
    Hi BDaddy. Thank you for the advice.

    I don't completely understand your suggestion. If you have time I'd appreciate if you could go into a little more detail.

    2h
     
  5. LionFische

    LionFische

    Joined:
    Oct 16, 2015
    Posts:
    107
    Hi BDaddy, I think I have the issue sorted. With help from other forum members, I was working with the layers also and I think in a similar way to the one you suggested.

    Anyway, my mistake was a silly one. I hadn't gone to the Inspector component for my script and selected the layerMask layer. Other then that, I think it was functioning okay.

    I'm testing now, it seems to be functioning. Fingers crossed.

    Thank you for the suggestion,

    2h
     
  6. bigmisterb

    bigmisterb

    Joined:
    Nov 6, 2010
    Posts:
    4,221
    I think there is room for improvement in the logic of your work here.

    Check out the changes I have made to your original script and see if the logic works better.

    Code (csharp):
    1.  
    2. public class PatrolDetection : MonoBehaviour
    3. {
    4.  
    5.     public LayerMask sightBlockingLayers;
    6.  
    7.     public RaycastHit hit;
    8.  
    9.     public float maxRayCastRange = 500.0f;
    10.  
    11.     //general detection
    12.     public bool isDetected = false;
    13.     //can see target
    14.     public bool canSee = false;
    15.  
    16.     void OnTriggerStay(Collider other)
    17.     {
    18.         if (!other.gameObject.CompareTag("Player"))
    19.             return;
    20.  
    21.         canSee = false;
    22.         Ray ray = new Ray(transform.position, other.transform.position - transform.position);
    23.         if (Physics.Raycast(ray, out hit, maxRayCastRange))
    24.         {
    25.             if (hit.collider == other)
    26.             {
    27.                 Debug.Log("The " + other + " is staying in the collider");
    28.                 canSee = true;
    29.                 Debug.DrawLine(transform.parent.position, hit.point);
    30.             }
    31.         }
    32.     }
    33.  
    34.     void OnTriggerEnter(Collider other)
    35.     {
    36.         if (other.gameObject.CompareTag("Player"))
    37.             isDetected = true;
    38.     }
    39.  
    40.     void OnTriggerExit(Collider other)
    41.     {
    42.         if (other.gameObject.CompareTag("Player"))
    43.         {
    44.             isDetected = false;
    45.             canSee = false;
    46.             Debug.Log("The " + other + " exited the collider");
    47.         }
    48.     }
    49. }
     
  7. LionFische

    LionFische

    Joined:
    Oct 16, 2015
    Posts:
    107
    Hi Bob, tried that but not working.

    I'm not sure what has gone wrong, my patrol has now also stopped following my player, Nightmare! I have two scripts.

    The moveEnemy is dependent on the canSee bool.

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. //This allows for the use of lists
    4. using System.Collections.Generic;
    5.  
    6. public class PatrolController : MonoBehaviour {
    7.    
    8.     public List<Transform> wayPointsList = new List<Transform>();
    9.  
    10.     public Transform currentWaypoint;
    11.  
    12.     public Transform currentPatrolTarget;
    13.  
    14.     public int wayPointNumber = 0;
    15.    
    16.     public float speed =4f;
    17.  
    18.     public float turnSpeed = 1f;
    19.  
    20.     public PatrolDetection PT;
    21.  
    22.     //NavMeshAgent Componants -> Navigation
    23.     public NavMeshAgent navAgent;
    24.  
    25.     // Use this for initialization
    26.     void Start () {
    27.         currentWaypoint = wayPointsList [wayPointNumber];
    28.     }
    29.    
    30.     // Update is called once per frame
    31.     void Update () {
    32.         moveEnemy ();
    33.     }
    34.    
    35.     public void moveEnemy()
    36.     {
    37.         if (GameObject.Find ("Player") != null && PT.canSee == true)
    38.         {
    39.             Debug.Log ("The Player is detected seen!");
    40.             currentPatrolTarget = GameObject.Find ("Player").transform;
    41.             navAgent.SetDestination(currentPatrolTarget.position);
    42.         }
    43.         else
    44.         {
    45.             if(navAgent.remainingDistance <= navAgent.stoppingDistance)
    46.             {
    47.                 if (wayPointNumber != wayPointsList.Count - 1) {
    48.                     wayPointNumber++;
    49.                     navAgent.SetDestination(wayPointsList [wayPointNumber].position);
    50.                 }
    51.                 else
    52.                 {
    53.                     wayPointNumber = 0;
    54.                     navAgent.SetDestination(wayPointsList [wayPointNumber].position);
    55.                 }  
    56.  
    57.             }
    58.         }
    59.     }
    60.  
    61. }
    The other script I have reverted back as the suggested way was producing similar results.

    2h
     
  8. LionFische

    LionFische

    Joined:
    Oct 16, 2015
    Posts:
    107
    Got the Patrol back tracking me...still casting through walls though.
     
  9. bigmisterb

    bigmisterb

    Joined:
    Nov 6, 2010
    Posts:
    4,221
    OK, I see your problem. I did re-write what you had to make it a little simpler.

    You get the frist waypoint, but never set the navAgent's destination. So obviously, it is never close to the destination, so it never gets started.

    Code (csharp):
    1.  
    2. public class PatrolDetection : MonoBehaviour
    3. {
    4.  
    5.     public float maxRayCastRange = 500.0f;
    6.  
    7.     public Transform target;
    8.  
    9.     void OnTriggerStay(Collider other)
    10.     {
    11.         target = null;
    12.         if (!other.gameObject.CompareTag("Player"))
    13.             return;
    14.  
    15.         RaycastHit hit;
    16.         Ray ray = new Ray(transform.position, other.transform.position - transform.position);
    17.         if (Physics.Raycast(ray, out hit, maxRayCastRange))
    18.         {
    19.             if (hit.collider == other)
    20.             {
    21.                 target = other.transform;
    22.                 Debug.DrawLine(transform.parent.position, hit.point);
    23.             }
    24.         }
    25.     }
    26.  
    27.     void OnTriggerExit(Collider other)
    28.     {
    29.         if (other.gameObject.CompareTag("Player"))
    30.         {
    31.             target = null;
    32.             Debug.Log("The " + other + " exited the collider");
    33.         }
    34.     }
    35. }
    36.  
    37. public class PatrolController : MonoBehaviour
    38. {
    39.     public List<Transform> wayPointsList = new List<Transform>();
    40.     public Transform currentWaypoint;
    41.     public Transform currentPatrolTarget;
    42.     public int wayPointNumber = 0;
    43.     public float speed = 4f;
    44.     public float turnSpeed = 1f;
    45.     private bool chasing = false;
    46.  
    47.     public PatrolDetection PT;
    48.  
    49.     //NavMeshAgent Componants -> Navigation
    50.     public NavMeshAgent navAgent;
    51.  
    52.     // Use this for initialization
    53.     void Start()
    54.     {
    55.         currentWaypoint = wayPointsList[wayPointNumber];
    56.         navAgent.SetDestination(currentWaypoint.position);
    57.     }
    58.  
    59.     // Update is called once per frame
    60.     void Update()
    61.     {
    62.         moveEnemy();
    63.     }
    64.  
    65.     public void moveEnemy()
    66.     {
    67.         if (PT.target != null)
    68.         {
    69.             navAgent.SetDestination(PT.target.position);
    70.             chasing = true;
    71.         }
    72.         else
    73.         {
    74.             if (chasing) {
    75.                 navAgent.SetDestination(currentWaypoint.position);
    76.                 chasing = false;
    77.             }
    78.             if (navAgent.remainingDistance <= navAgent.stoppingDistance)
    79.             {
    80.                 wayPointNumber = (++wayPointNumber) % wayPointsList.Count;
    81.                 currentWaypoint = wayPointsList[wayPointNumber];
    82.                 navAgent.SetDestination(currentWaypoint.position);
    83.             }
    84.         }
    85.     }
    86. }
    87.  
     
  10. LionFische

    LionFische

    Joined:
    Oct 16, 2015
    Posts:
    107
    Hi Big.

    I've actually got the nav back working. I've had a look at your script and tried it but it's not causing the patrol to follow the player.

    The issue now is the raycast. It's still going through walls.

    Thank you for the help. I hope we can get to the bottom of this!

    2h