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

Raycast Ignore Own Collider Without Layers

Discussion in 'Scripting' started by astellato, Nov 13, 2010.

  1. astellato

    astellato

    Joined:
    Nov 13, 2010
    Posts:
    5
    Is there a way to do this?

    I've got an object I wish to duplicate many times. I don't want to use layers because I want the raycast to hit the duplicate's SphereCollider, just not each one's own collider.

    Tried to move the origin of the raycast to the edge of collider, but so far I have been unsuccessful. Do I need to RaycastAll? Can someone point me in the right direction?

    Here's a simple example C# script. It continually hits itself.

    Code (csharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class SimpleAI : MonoBehaviour {
    5.     public float speed = 20;
    6.     public float rotateSpeed = 10;
    7.     public RaycastHit hit;
    8.  
    9.     void Start () {
    10.         //
    11.     }
    12.    
    13.     // Update is called once per frame
    14.     void Update () {
    15.         //SphereCollider mCollider = (SphereCollider)GetComponent(typeof(SphereCollider));
    16.                 //Vector3 adjOrigin = transform.position + Vector3.forward * mCollider.radius;
    17.         if(!Physics.Raycast(transform.position, transform.forward, out hit, 10)){
    18.             transform.Translate(Vector3.forward * speed * Time.smoothDeltaTime);
    19.         } else {
    20.             if(hit.collider.gameObject.tag == "npc"){
    21.                 Debug.Log("I hit myself, or someone in my group.");
    22.             } else if(hit.collider.gameObject.tag == "player"){
    23.                 Debug.Log("I hit the player");
    24.                 transform.Rotate(Vector3.up, 90 * rotateSpeed * Time.smoothDeltaTime);
    25.             } else if(hit.collider.gameObject.tag == "ground"){
    26.                 Debug.Log("I hit the ground.");
    27.             } else {
    28.                 Debug.Log("Something is seriously messed up.");
    29.             }
    30.         }
    31.     }
    32. }
     
  2. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    Just try RaycastAll. You may have another member variable that is initialized on Start or Awake.
    Code (csharp):
    1. private SphereCollider ownCollider;
    2.  
    3. void Start () {
    4.     ownCollider = GetComponentInChildren <SphereCollider> ();
    5. }
    Now you simply have to ignore 'ownCollider' when checking the array you are getting with 'RaycastAll'.
    It's straight forward, as long as you don't get performance issues.
     
    Filip8429 likes this.
  3. dlcl

    dlcl

    Joined:
    Oct 15, 2010
    Posts:
    33
    Hi guys,

    I'm having a similar issue to the OP, in that I'm trying to prevent a raycast (fired from a hand-held weapon) from detecting the collider of the parent object (Player) that it is attached to.

    I've gotten as far as creating a private Collider variable that is set to the root object's collider (in this case, the Player), then only applying damage if the raycast doesn't hit the Player's collider. Code snippet below:

    Code (csharp):
    1.  
    2. public class BurstRifle : MonoBehaviour
    3. {
    4.     private Collider ownCollider;
    5.  
    6.     void Start ()
    7.     {
    8.         // Set the weapon owner's collider as ownCollider.
    9.         ownCollider = transform.root.gameObject.GetComponent<Collider>();
    10.     }
    11.  
    12.     void  FireOneShot ()
    13.     {
    14.         Vector3 direction= transform.TransformDirection(Vector3.forward);
    15.         RaycastHit hit = new RaycastHit();
    16.        
    17.         // Did we hit anything?
    18.         if (Physics.Raycast (transform.position, direction, out hit, range))
    19.         {
    20.             // Test to ensure we don't damage ourselves.
    21.             if (!ownCollider)
    22.                 // Send a damage message to the hit object         
    23.                 hit.collider.SendMessageUpwards("ApplyDamage", damage, SendMessageOptions.DontRequireReceiver);
    24.         }
    25.     }
    26. }
    27.  
    Using the above code, the Player's gunshots no longer hurts himself... but it now does no damage to enemies either. I'm not 100% familiar with raycasting code, but I'm guessing that I need to use RaycastAll to get the gunshots to register on enemy colliders if I'm ignoring the Player's own collider.

    After many hours(!) trying to make heads from tails of the RaycastAll API document, I really have no idea how to convert my existing RaycastHit behaviour into RaycastAll, especially as RaycastAll looks like it also uses arrays (another C# coding syntax that I haven't fully grasped yet).

    Any conversion help, or even a better explanation as to why my code is preventing gunshots from damaging enemy colliders, would be much appreciated!
     
  4. PunsAndAmmo

    PunsAndAmmo

    Joined:
    Jan 16, 2011
    Posts:
    20
    Right now it looks like your hit checking code is only checking to see if ownCollider exists at all, not if that was what was hit.

    I may be wrong of course (fairly new at this) but that's jumping out at me.

    Maybe try replacing !ownCollider with (hit.collider != ownCollider) or something of the sort.

    edit: this is to dlcl
     
    Last edited: Jan 17, 2011
  5. dlcl

    dlcl

    Joined:
    Oct 15, 2010
    Posts:
    33
    @PunsAndAmmo

    You, Sir, are a gentleman and a saint. You've nailed the problem right on the head. Using if(hit.collider != ownCollider) fixed the problem. Thanks!
     
  6. PunsAndAmmo

    PunsAndAmmo

    Joined:
    Jan 16, 2011
    Posts:
    20
    Well, all I have is a hammer....

    Also, glad I could help!
     
  7. Tsilliev

    Tsilliev

    Joined:
    Jan 21, 2014
    Posts:
    34
    Code (CSharp):
    1.  ownCollider = transform.root.gameObject.GetComponent<Collider>();
    I get errors because I am writing in java. :(
     
  8. Dantus

    Dantus

    Joined:
    Oct 21, 2009
    Posts:
    5,667
    As your issue isn't the same one as in this thread, you should start a new one.
     
  9. Kironde-Namusanga

    Kironde-Namusanga

    Joined:
    Dec 11, 2014
    Posts:
    12
    A very good solution is temporarily disable your collider, make the raycast hit and then activate it again after the raycast
     
  10. OblicaStudio

    OblicaStudio

    Joined:
    Feb 20, 2021
    Posts:
    30
    Or you can simply disable it in the Player Setting >> Physics 2D >> Queries Start In Colliders >> Uncheck
     
    Last edited: Jul 11, 2022
    Czepig likes this.