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

Make raycast pass through trigger and still register?

Discussion in 'Scripting' started by Alabatross, Oct 17, 2013.

  1. Alabatross

    Alabatross

    Joined:
    Dec 15, 2012
    Posts:
    223
    I'm attempting to add a bullet whiz sound effect for when a shot goes near you. To do this id create a spherical trigger around the player. What I want to do is, if the shot (a raycast) passes through this sphere, it will still continue on while making the player hear a whiz sound.

    Is this possible? Can the raycast tell the difference between a trigger and a solid collider? Or do both stop it
     
  2. foxter888

    foxter888

    Joined:
    May 3, 2010
    Posts:
    530
    if you make it a trigger it will go through which is what you would want or you could just have the bullet already play a sound instead
     
    vladkozulin likes this.
  3. GibTreaty

    GibTreaty

    Joined:
    Aug 25, 2010
    Posts:
    792
    In Edit>Physics there is an option called Raycasts Hit Triggers that is ticked on by default. If you want your bullet to detect the trigger but still continue on you can use Physics.RaycastAll. It gives you a list of RaycastHits and the colliders referenced in it will have a variable that says whether it's a trigger or not (collider.trigger). It doesn't give the RaycastHits in order so you'll have to rearrange them yourself if need-be. Hope that helps!
     
  4. Alabatross

    Alabatross

    Joined:
    Dec 15, 2012
    Posts:
    223
    That seems like it'd be a hog on the cpu to sort and check every time a bullet is shot, would it not?

    I can't believe the idea of a trigger is only relevant to game objects and not raycasts. Kind of inconsistent of Unity



    the bullet is not a physical object
     
  5. JamesLeeNZ

    JamesLeeNZ

    Joined:
    Nov 15, 2011
    Posts:
    5,616

    1. No. Raycasts are cheap.

    2. You can set the option, so I would hardly consider this inconsistant. Most people are not interesting in raycasting trigger colliders.
     
  6. Alabatross

    Alabatross

    Joined:
    Dec 15, 2012
    Posts:
    223
    1. I meant sorting and then checking every time a weapon is shot

    2. I mean pass through a trigger and still detect it (and continue moving on) It would affect no one because they could choose not to do anything with the collision


    By inconsistent I mean a gameObject can pass through a trigger, and the gameObject's physics are unaffected yet it still throws up a collision. Why can't raycasts do the same thing? They should have a collision for when they hit a trigger (but they continue to cast)

    Basically why don't raycasts have a non-obstructive method of collision detection. They can still cast and hit a solid object and stop, but why can't it let me know of any trigger it passed through on the way?
     
    Last edited: Oct 18, 2013
  7. Alabatross

    Alabatross

    Joined:
    Dec 15, 2012
    Posts:
    223
    any other word on this?
     
  8. hpjohn

    hpjohn

    Joined:
    Aug 14, 2012
    Posts:
    2,190
    This seems like a very limited use scenario, (so the default is to not do it to save on the majority of cases) and there's an option for the cases where it is needed, with raycastAll and raysHitTriggers. I don't see the problem.

    If you want to minimize the number of colliders that a raycastall collects, do the regular raycast first to hit a single solid collider, then use the distance of that solid to perform the raycastall only between here and there.

    Or maybe even use a slightly shorter distance to collect only those bodies between source and solid (you'll probably get the solid again otherwise)
     
  9. Alabatross

    Alabatross

    Joined:
    Dec 15, 2012
    Posts:
    223
    But doesn't that mean triggers will stop the ray just like a solid object?

    Ill give your second option a shot though
     
  10. JamesLeeNZ

    JamesLeeNZ

    Joined:
    Nov 15, 2011
    Posts:
    5,616
    You shouldnt need to sort it... why are you sorting it?

    They dont throw collision events, they throw trigger events. Slightly different.

    http://docs.unity3d.com/Documentation/Manual/Physics.html Have a look at the collision action matrix

    Raycasts are designed to be cheap. The cheapest way to run is to return as soon as you find the closest 'hit'. Its why they provide the other version which returns all hits in a raycast.
     
  11. hpjohn

    hpjohn

    Joined:
    Aug 14, 2012
    Posts:
    2,190
    Youll need to be smart with layers masks
     
  12. Alabatross

    Alabatross

    Joined:
    Dec 15, 2012
    Posts:
    223
    I feel like a workaround like this is a bit too much for such a simple thing

    Perhaps I'm thinking about it all wrong? Is there a better way to approach a bullet flyby?


    "Casts a ray through the scene and returns all hits. Note that order is not guaranteed."

    If I do raycast all and the player is between two walls ill have to sort them by distance so the player doesn't get a bullet whiz when the bullet didn't actually make it to them. Doing that with 60 people shooting at you could be a memory hog would it not?
     
    Last edited: Oct 21, 2013
  13. JamesLeeNZ

    JamesLeeNZ

    Joined:
    Nov 15, 2011
    Posts:
    5,616
    You dont have to sort them though.. you can have conditions...

    ie raycast all.

    Did hit player : bool - capture distance
    Did hit playerWoosh: bool - capture distance

    Then you just need to check for conditions that are met that cover a shorter distance... ie walls, other players.

    This doesnt take into account the chance for multiple near misses... however, if this was my project, I wouldnt be worrying about raycasts, I would be using rigidbody bullets that would do something on collision/trigger events, then you dont have to worry about all this.

    Code (csharp):
    1.  
    2.  
    3. bool playerHit;
    4. bool playerNearMiss;
    5. GameObject target;
    6.  
    7.  
    8. void Fire()
    9. {
    10.    float maxDistance = 999999;
    11.    nearMissTargets.Clear();
    12.  
    13.    RaycastHit[] hits;
    14.    hits = Physics.RaycastAll(transform.position, transform.forward, 100.0F);
    15.    for(int x=0;x<hits.length;x++)
    16.    {
    17.       if(hits[x].tag == "player"  hits[x].distance < maxDistance)
    18.       {
    19.         playerHit = true;
    20.         target = hits[x].transform.gameObject;
    21.         maxDistance  =  hits[x].distance;
    22.       }
    23.       else if(hits[x].tag == "playerNearMiss"  hits[x].distance < maxDistance)
    24.       {
    25.         playerNearMiss = true;
    26.         target = hits[x].transform.gameObject;
    27.         maxDistance  =  hits[x].distance;
    28.       }
    29.       else if(hits[x].distance < maxDistance)
    30.       {
    31.          playerHit = false;
    32.          playerNearMiss = false;
    33.          maxDistance = hits[x].distance;
    34.       }
    35.    }
    36.  
    37.    //if hit apply damage and return
    38.    
    39.    //if near miss play sound
    40.  
    41.  
    42. }
    43.  
    44.  
    45.  
     
  14. Alabatross

    Alabatross

    Joined:
    Dec 15, 2012
    Posts:
    223
    Having an instant hit response with a physical bullet is near impossible from what I remember, they move so fast even continuous dynamic rarely detects it. There are many pluses to using real bullets though so its quite possible I'm just missing something. Actually I think I may have had rigidbody bullets working in the past before I moved it to a raycast. Getting my memories mixed up.


    As for the script, that's an interesting approach to it hmm

    I just didn't want to rip it up again swapping it back to rigid bullets if I didn't have to, but I probably will because of the benefits of bullet drop
     
    Last edited: Oct 21, 2013