Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Physics.OverlapSphere problem, "seeing" through objects.

Discussion in 'Getting Started' started by Oskar_Kasprzak, Mar 30, 2017.

  1. Oskar_Kasprzak

    Oskar_Kasprzak

    Joined:
    Mar 26, 2016
    Posts:
    61
    Hello there.

    I am not sure if there's something wrong with my code or if that's how it should work. So I am making some game where you get auto-generated maze and I wanted to put some "enemies" in there. They're comming to you as they see you. The problem is that when using triggers they can "see" you through walls. Maybe they don't go through walls, but they try to. Later when you get into this point you can see few monsters waiting for you. So I decided to go with raycasts to check if enemy can actually see player. Here is my code:

    Code (csharp):
    1.  
    2.     void OnTriggerStay(Collider other) {
    3.         if (other.CompareTag("Player")) {
    4.             hitColliders = Physics.OverlapSphere(transform.position, sphereRadius);
    5.      
    6.             for (int i = 0; i < hitColliders.Length;i++ ) {
    7.                 if (hitColliders[i].CompareTag("Player"))
    8.                 {
    9.  
    10.                     if (Vector3.Distance(target.position, transform.position) > 1.5f)
    11.                     {
    12.                         transform.LookAt(target);
    13.                         transform.position += transform.forward * movspeed * Time.deltaTime;
    14.                     }
    15.                 }
    16.             }
    17.         }
    18.     }
    19.  
    When I get out of their sphere, they stop following me, fine. But I've put giant cube on scene and whenever I am behind it, the enemy is still trying to get me... so that didn't work any better than with only triggers. I am doing something wrong?

    Please let me know if you know any way to make it work nicely. Monsters trying to go into walls don't look very good to be honest.

    Best regards.
     
  2. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,842
    I don't see any raycasts in that code. Raycasts are indeed the correct way to do visibility testing (in most cases).

    Read through the docs for Physics.Raycast... there are many overloads of that method, but the docs include a simple example for each one.
     
  3. LaneFox

    LaneFox

    Joined:
    Jun 29, 2011
    Posts:
    7,384
    OverlapSphere returns every collider in the radius on the given layermask. So basically, yeah, you can 'see' everything because thats exactly what you would expect.

    For each of those hits you'll want to do a line-of-sight check to confirm that there is visibility to the target. Use Physics.Raycast for that. On confirmed targets you'll put them in a list of enemies that are 'known' and can be pursued or a last known position of the target being pursued. Otherwise as soon as LoS is broken they'll stop.
     
    spiritworld likes this.
  4. Oskar_Kasprzak

    Oskar_Kasprzak

    Joined:
    Mar 26, 2016
    Posts:
    61
    You just enlightened me. Thanks for spending your time for replaying :) Have a nice day.
     
    RedHeart95 likes this.
  5. spiritworld

    spiritworld

    Joined:
    Nov 26, 2014
    Posts:
    29
    Thanks for the idea I initially had just raycast which felt it needed too much accuracy (as in, you must look directly into target) and then spherecast was too broad, it detected things behind walls etc. So here's my combined spherecast + raycast detector for objects with imaginary component "MyTarget"

    Code (CSharp):
    1.             RaycastHit[] raycastHits = new RaycastHit[4];
    2.             int hits = Physics.SphereCastNonAlloc(rayStart, 0.2f, rayDirection, raycastHits, rayDistance, layerMask);
    3.             if (hits > 0)
    4.             {
    5.                 for (int i = 0; i < hits; i++)
    6.                 {
    7.                     myTarget = raycastHits[i].transform.GetComponent<MyTargetComponent>();
    8.                     if (myTarget != null)
    9.                     {
    10.                         // check visible
    11.                         if (Physics.Raycast(rayStart, rayDirection, out raycastHit, rayDistance, layerMask))
    12.                         {
    13.                             // it's visible, break out of the loop
    14.                             if (myTarget.IsInteractable)
    15.                             {
    16.                             // do stuff
    17.                             }
    18.                             break;
    19.                         }
    20.                     }
    21.                 }
    22.             }
    23.         }
    EDIT: not working, my raycast detects the last collider, so if there's 2 objects in line it hits the one behind, not in front. Gotta check why.
     
    Last edited: May 14, 2022