Search Unity

Physics.Raycast misses randomly

Discussion in 'Physics' started by komatii, Jun 7, 2011.

Thread Status:
Not open for further replies.
  1. komatii

    komatii

    Joined:
    Sep 8, 2010
    Posts:
    58
    I'm using Physics.Raycast on my bullets to determine if they hit something, however it doesn't always work.
    The part that makes it weird, is that I can repeatedly fire bullets at the same object, from the exact same angle and watch as most hit, but occasionally one misses.
    Other times, I can get a situation where every single bullet misses an object as the raycast fails, but if I pause the game and step through frame by frame, every bullet hits. I get this with both box colliders and mesh colliders.

    The bullet object itself has it's axis at the trailing end. The physics.raycast uses this axis point as the origin, and the position for next frame plus 5% to ensure a bit of overlap to prevent it from missing surfaces lying right at the origin.

    The raycast is done in the bullet objects Update() function.
     
  2. MattFS

    MattFS

    Joined:
    Jul 14, 2009
    Posts:
    219
    I get similar issues as well with raycast...
    I even moved all raycasting code to FixedUpdate() and still got random misses.
    It's extremely frustrating. Further to this, in Editor I get almost 0% misses which is great... but any other platform or build and there's almost a 50% hit miss...

    What could be causing this?
     
  3. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    You'll possibly want to do it in fixed update.
     
  4. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    I've never seen a raycast miss, in the editor or a build. I don't think it's mathematically possible. The thing to watch out for in certain cases is that you need to be aware of the order in which you move rigidbodies and do raycasts, because otherwise it's possible that colliders aren't actually where they appear to be. So the raycast appears to "miss" a collider but that's actually not what's happening--it's a legitimate miss because the collider isn't really there, it's using the position from the previous physics frame, since it hasn't actually been moved yet. (Yeah, I ran into that issue a while ago, it was a bit confusing at first....)

    --Eric
     
    unity_NunFZ56vXt37EA and Regone like this.
  5. MattFS

    MattFS

    Joined:
    Jul 14, 2009
    Posts:
    219
    ah sure, thanks for the heads up Eric I'll look into!
     
  6. rageingnonsense

    rageingnonsense

    Joined:
    Dec 3, 2014
    Posts:
    99
    I know this is an old thread, but I do see this happen. I don't think it has to do with FixedUpdate() necessarily, as I see it happen when raycasting against colliders that do not even move.

    I'm pretty sure that it can also happen due to floating point precision issues, and therefore mathematically possible due to that. It does not happen often, but it DOES happen (and very annoying when it does).

    It also happens sometimes when raycasting against a very flat collider.
     
    TinyTeaOW likes this.
  7. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    No, it doesn't happen. If if did, it would be classified as an urgent Unity bug to be fixed ASAP. If you're confident it is, file a bug. More likely:

    - your ray really isn't where you think it is - draw a debug ray that correctly matches it.
    - the ray begins inside a collider
    - there's colliders you're not sure of
    - you transform the ray direction and position too fast and skip

    Unless you're 10-20k units out, I doubt it's a precision issue. If you are more than 10-20k units out you'd best look at how your game is structured (start having all kinds of issues with bigger spaces, not just physics), assuming 1 meter = 1 unit with a humanoid reference scale.
     
  8. NidoAnxari

    NidoAnxari

    Joined:
    Jan 2, 2017
    Posts:
    86
    Actually, this is also happening with me. When I rotate my GameObject most of the time reflected ray doesn't show up.
     
    Split3 and Dr-Trax like this.
  9. Dr-Trax

    Dr-Trax

    Joined:
    Mar 16, 2018
    Posts:
    10
    It misses a lot! I have a flickering debug ray.
     
    PNUMIA-Rob and Split3 like this.
  10. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    Is it far from the origin? You should probably post some code or try to narrow it down.
     
  11. Dr-Trax

    Dr-Trax

    Joined:
    Mar 16, 2018
    Posts:
    10
    RaycastHit2D hit = Physics2D.Raycast(transform.position, transform.up);
    arrowLine.SetPosition(0, transform.position);
    arrowLine.SetPosition(1, hit.point);
    RaycastHit2D hit2 = Physics2D.Raycast(hit.point, Vector2.Reflect(transform.up, hit.normal));
    arrowLine.SetPosition(2, hit2.point);
     
  12. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    Yeah is it in fixedupdate?
     
  13. Dr-Trax

    Dr-Trax

    Joined:
    Mar 16, 2018
    Posts:
    10
    Neither FixedUpdate nor Update is working.
     
  14. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    That wasn't my question. Are you aware fixedupdate can be called at a different frequency to update, it would likely cause some debug flickering.
     
  15. Dr-Trax

    Dr-Trax

    Joined:
    Mar 16, 2018
    Posts:
    10
    I am aware of that.
    The origin of the Raycast is rotating. I tried to update the Line Renderer in both Updates and still the reflecting Material flickers the same as the Debug Ray.
     
    Last edited: Apr 1, 2018
  16. chadfranklin47

    chadfranklin47

    Joined:
    Aug 11, 2015
    Posts:
    226

    Apparently, my Raycast isn't hitting my Capsule Collider. I have a zombie character that I enable the ragdoll (all of the collider GameObjects) once the health reaches zero. I then shoot a Raycast at it to apply force to the hit Ragdoll component, but the Raycast fails about 10 - 20% of the time. Both of these things happen in the same frame, I don't know if that could be the reason. The Raycast originates from input which is calculated in the Update Method.

    It could be just an editor thing, but one thing that troubles me is that when I call Debug.Break() in the case that the Raycast fails, It takes about half a second to show that the collider GameObject is active, and a few seconds to show the green collider outline in the scene view.

    My current solution is to try the Raycast again next frame in a coroutine which hasn't failed yet, but that is only if I can not sort this out. I also used Debug.DrawLine to see the ray in the scene view and it goes straight through the collider. My Collision Mask is set to Dead Ragdoll and a few others, and my testGo object from the debug code is set to the head.

    I have attached a screenshot of the Editor as well as my Raycast and the Debug code. Please help.

    Screenshot_1339.png Screenshot_1342.png
     
  17. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    What is collisionMask's value?
     
  18. chadfranklin47

    chadfranklin47

    Joined:
    Aug 11, 2015
    Posts:
    226
    Dead Ragdoll and Ragdoll.

    Screenshot_1351.png
     
    Last edited: Jan 25, 2019
  19. bart_the_13th

    bart_the_13th

    Joined:
    Jan 16, 2012
    Posts:
    498
    Is there any chance that the raycast starts inside any collider?
     
  20. chadfranklin47

    chadfranklin47

    Joined:
    Aug 11, 2015
    Posts:
    226
    Definitely not at the time of the error:

    Screenshot_1350.png
     
  21. chadfranklin47

    chadfranklin47

    Joined:
    Aug 11, 2015
    Posts:
    226
  22. chadfranklin47

    chadfranklin47

    Joined:
    Aug 11, 2015
    Posts:
    226
    Well, that was fast, and no, unfortunately, updating to 2018.3.3f1 did not help.
     
  23. chadfranklin47

    chadfranklin47

    Joined:
    Aug 11, 2015
    Posts:
    226
    Sorry for so many updates...

    I changed my zombie ragdoll code to not enable the zombie ragdoll GameObjects then move the ragdoll transforms to the correct positions, but instead to move the disabled ragdoll transforms to the correct positions, then enable the GameObjects and so far the error hasn't occurred.

    Could this have something to do with FixedUpdate not aligning with Update all the time and moving the collider a bit late 10-20% of the time even though the transform was in the correct position? This would explain the error only occurring sometimes.

    Edit: Apparently this causes another error with my ragdoll, but not the topic of this forum thread.

    If anyone sees this and wants to know, the solution was to move both the transform.position and ragdoll.position.
     
    Last edited: Feb 2, 2019
    LaurieAnnis likes this.
  24. nsfnotthrowingaway

    nsfnotthrowingaway

    Joined:
    Feb 18, 2016
    Posts:
    48
    Just in case this helps anyone, I had a problem with raycasts frequently missing and flickering as I dragged the mouse, which was casting a screenpointtoray of length float.postiveinfinity. The problem ended up being the near and far clipping planes of the camera. I had them set to an unnecessarily huge difference, and I guess the raycasts normalize somehow to the distance and introduce floating point errors (that's my hunch at least)[EDIT: better hunch in my post below]. Regardless, shrinking the distance between them to something still huge, but more reasonable gave me completely consistent and stable raycasts.
     
    Last edited: Feb 10, 2019
  25. chadfranklin47

    chadfranklin47

    Joined:
    Aug 11, 2015
    Posts:
    226
    I couldn't imagine raycasts that long being a good idea. How big is your world?
     
  26. nsfnotthrowingaway

    nsfnotthrowingaway

    Joined:
    Feb 18, 2016
    Posts:
    48
    @chadfranklin47
    Infinity is the default for raycast length. I guess the issue is probably that ScreenPointToRay needs to take into account near clipping plane as opposed to just the z position when firing a ray, which makes sense, but wasn't intuitively the place to look when trying to troubleshoot Physics.Raycast. I was just experimenting with some 2d orthographic visualization, and I made the near and far clipping planes arbitrarily huge. The distance between the near clipping range and some of the objects in the far clipping range was introducing floating point precision issues since the objects weren't particularly far apart.
     
    Last edited: Feb 10, 2019
  27. DanJa512

    DanJa512

    Joined:
    Dec 14, 2015
    Posts:
    18
    I know this is super old, but I just spent a long time figuring out that any kind of raycast to hit a collider attached to an object with a non-kinematic rigidbody AND A NAVMESH AGENT will return extremely inconsistent hits. The rigidbody should be kinematic in this case.
     
    Declius likes this.
  28. blablaalb

    blablaalb

    Joined:
    Oct 28, 2015
    Posts:
    53
    I also have problems with SphereCast. I'm doing SpehreCast to detect if a player is standing on a ground.. The SphereCast randomly gives incorrect results, it may return few trues and then suddenly return false even when nothing changes.
    I move my character with Rigidbody.Move and check the ground in order to determine if the character is standing or is falling. If SphereCast() evaluates to false fall animation is triggered. The problem is that it returns false even when the character is firmly standing on the ground. The output looks something like this:
    True
    True
    True
    False
    True.

    The False should not have happened. I put Debug.Break() right after SphereCast and I know for sure that the character was standing on the ground when the SphereCast returned false.
     
  29. halivudestevez

    halivudestevez

    Joined:
    May 12, 2019
    Posts:
    14
    me too.... yesterday it was great, now it is not... I even tried to put in to a coroutine...
    ofcourse it can be my fault too...
     
  30. halivudestevez

    halivudestevez

    Joined:
    May 12, 2019
    Posts:
    14
    I solved mine: an invisible object was in the way with collider. I took off its collider, now everything is fine.
    On hit, check, what object was hit.
     
  31. GazingUp

    GazingUp

    Joined:
    Jun 16, 2015
    Posts:
    271
    I know this is an old topic but I found something interesting about RayCasts. If you modify the position of a GO in one of the trigger events, in fixedUpdate, the raycast will not reflect the position of that GO's position (I had something that was triggering from an onTrigger event and checking that on fixedUpdate) Moving this to update fixed it. It seems Update reflects the raycast instantly along with the GO's position after the onTrigger Event.
     
  32. AlTheSlacker

    AlTheSlacker

    Joined:
    Jun 12, 2017
    Posts:
    326
    @GazingUp
    At the risk of yet another tangent / necro... I believe what you are seeing is the influence of the Unity execution order: https://docs.unity3d.com/Manual/ExecutionOrder.html where your trigger is activating on the completion of a physics cycle and before the Update. Worth considering that you may have more than one Physics cycle run before a single Update runs, so I believe running your raycast from Update may miss some transitory hits.
     
  33. GazingUp

    GazingUp

    Joined:
    Jun 16, 2015
    Posts:
    271
    Yeah still a tricky bit for me. But if that's the case how come there's a delay in the raycast when it's in fixed update?
    Example, ontriggerexit change the transform position of the GO , in fixed update the position would've changed but the raycast would still be in it's previous position. But in update, the raycast catches up instantly.
     
  34. AlTheSlacker

    AlTheSlacker

    Joined:
    Jun 12, 2017
    Posts:
    326
    Check the link I sent - Events run after the FixedUpdate method, which runs at the start of the physics loop.

    FixedUpdate - runs before trigger events. Raycast is with the current GO position
    TriggerEvents - runs after FixedUpdate. You modify the GO position from this event method (if I understand correctly)
    Update runs - RayCast here should see the new/modified GO position from the event.

    Complications: The physics loop may run more than once between Updates (or not at all, depending on step sizes and load).
     
  35. GazingUp

    GazingUp

    Joined:
    Jun 16, 2015
    Posts:
    271
    But why didn't the raycast change position with the GO when it changed in the trigger event? It looks like raycast work separate from the GO.
     
  36. FlightOfOne

    FlightOfOne

    Joined:
    Aug 1, 2014
    Posts:
    668
    Since we are all reviving this I will join too! :p

    I am working on a custom projectile system and I had the same issue just now and I moved everything to fixed update (with time.FixedDeltaTime) and it started to work, great right? well the thing is I am not moving anything, and my objects don't even have rigidbodies, just a collider is all they have.

    Here's my problem and solution (rather a work around) in case anyone else have the same scenario and google brings you here. When I was updating (in Update()) my projectiles I was using Time.deltaTime to move and within this loop I also check for hits and hit check distance is the delta position. It turns out moving with Time.DeltaTime, once in a while a raycast would miss. I would think it would still work since it is all using the same deltaTime and distance but it didn't. It is highly likely I am missing something here but all I had to do was use Time.FixedDelta time (in Update()) and now it does not skip.
     
    xehster likes this.
  37. GazingUp

    GazingUp

    Joined:
    Jun 16, 2015
    Posts:
    271
    I have seen this occur if you are using fixedUpdate to take in the inputs for movement. If you move your inputs into update the rayCasts should move fine. FixedDeltaTime should be in fixedUpdate.
     
  38. FlightOfOne

    FlightOfOne

    Joined:
    Aug 1, 2014
    Posts:
    668
    Yeah, true, don't think you are supposed to capture inputs in FixedUpdate since it can get called multiple times within one update. I am using Update() for this.

    In any case, there was nothing wrong at the end... it was my brain going full stupid mode :confused: after working for over 14 hours. I had a reversed for-loop which made it appear like it was skipping the first and hitting the next. A good night of sleep and 2 minutes looking at it was all it took, no more skipping.:D
     
  39. Creepy_BrainZ

    Creepy_BrainZ

    Joined:
    Jan 19, 2019
    Posts:
    3
    The solution to this problem
    Don't use Polygon Collider because the ray will not go out
    Change the polygon collider to other collider like Capsule or Box or Circle
    100% Worked
     
  40. psbgames22

    psbgames22

    Joined:
    Dec 28, 2018
    Posts:
    3
    Thanks, It's worked for me.
     
  41. ecritter

    ecritter

    Joined:
    Jun 20, 2016
    Posts:
    10
    thank you very much!
     
  42. IronHelmet

    IronHelmet

    Joined:
    May 2, 2017
    Posts:
    85
    We just spent a few hours here discovering that raycasts and spherecasts into the top of Unity's Player Character Controller Capsule is inconsistent. Sometimes hits, sometimes misses.

    I think we are going to solve it by adding a second standard capsule collider just for projectile hits.
     
  43. WidmerNoel

    WidmerNoel

    Joined:
    Jun 3, 2014
    Posts:
    65
    Same issue here. I have a wall which is a static collider (not trigger) without any other components. And my projectiles sometimes (around 7% of the time) just fly straight through the wall. I tried raycasting and moving my projectiles in update (using deltaTime) and in fixed update (using fixedDeltaTime). Both did not improve the hit rate.

    Not sure if the execution order can be the problem if I am not moving my static collider. Any inputs would be appreciated :)
     
    rubendariohh likes this.
  44. Tristan-Moore

    Tristan-Moore

    Joined:
    Aug 22, 2014
    Posts:
    18
    I'm not sure if this would be related to the particular problem and this was a long thread so I couldn't read through it all, but raycast failures can be the result of not syncing physics transforms before you run the raycast. I've had a lot of problems with this because we built a codebase around having autoSyncTransforms set to true, but needed to disable it because of the overhead that comes with it (it's disabled by default now, but wasn't when we started the project).

    https://docs.unity3d.com/ScriptReference/Physics-autoSyncTransforms.html

    You don't have to turn on autoSyncTransforms to get it to work, you just have to call
    Code (CSharp):
    1. Physics.SyncTransforms();
    before the raycast in question. Unity used to do this automatically before any scene checks like raycasts were done, and it generally doesn't cause a problem if you don't sync manually, but there are some cases around timing of calls and how you manipulate objects that could cause either a position used for the raycast, or the object it hit, to not be accurate until the physics get synced that frame.

    Hopefully this helps at least someone who had this problem and didn't get it resolved via the various recommendations here.

    More in-depth explanation: https://thegamedev.guru/unity-cpu-performance/physics-autosynctransforms/
     
    darashayda likes this.
  45. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,428
    The cause of it is driving things via the Transform. The whole idea is that the physics system is supposed to be in charge of poses, not the Transform system. Having to call SyncTransforms means you're modifying Transforms and so create a situation where you then have to update physics to tell it you've done so. There might be a valid reason to modify Transforms but it can also be a bad habit, using the Transform system as the authority when using physics where the Rigidbody(2D) are supposed to be the authority including when its interpolating.

    When performing queries you use the Rigidbody(2D) pose (position/rotation) as a reference when performing the query. It is the authority on what the "real" pose it, not the Transform which is purely visual. During interpolation, for instance, the body is already at the target position, the Transform is just "moving there". It's common to use the Transform.position and wonder why things are not quite correct. Use Rigidbody(2D).position and it'll always be querying correctly.
     
    WidmerNoel and Tristan-Moore like this.
  46. Tristan-Moore

    Tristan-Moore

    Joined:
    Aug 22, 2014
    Posts:
    18
    That's definitely the problem that we ran into in our case. We chose to address it by changing our code to use the Rigidbody instead of the Transform, but used Physics.SyncTransforms for aspects of a purchased framework that weren't easy to completely re-write. So MelvMay is 100% right about that being the underlying reason in most cases, and why codebases that use the Rigidbody and not the Transform won't usually have issues with when physics sync.
     
    MelvMay likes this.
  47. eliteforcevn

    eliteforcevn

    Joined:
    Oct 25, 2018
    Posts:
    47
    edit: ok my problem is RaycastAll RaycastHit array need to be sort by distance before use

    im using raycats all and it not hit all colliders, some ray pass through collider :((

    upload_2023-2-16_5-46-7.png
     
    Last edited: Feb 15, 2023
  48. halley

    halley

    Joined:
    Aug 26, 2013
    Posts:
    2,420
    Man, this is a thread full of swamp gas that just won't die.

    Yeah, a lot of people don't realize that *CastAll* functions do NOT return their results sorted by distance. It's to save time. Did it hit? Do we have room in the array? Add it to the array. That's it.

    If you ONLY want the nearest one, or you ONLY want the nearest applicable one, then doing a highwater search is almost always better than sorting the whole array.

    Code (CSharp):
    1.         // pseudocode for a highwater search
    2.         {
    3.             Thing best = null;
    4.             float closestSq = float.PositiveInfinity;
    5.             float rangeSq = range*range;
    6.             foreach (Thing thing in SomeIterableOfAllThings)
    7.             {
    8.                 if (DoesntMeetCriteria(thing))
    9.                     continue;
    10.                 float dSq =
    11.                     (thing.transform.position - position).sqrMagnitude;
    12.                 if (dSq >= closestSq)
    13.                     continue;
    14.                 if (dSq > rangeSq)
    15.                     continue;
    16.                 best = thing;
    17.                 closestSq = dSq;
    18.             }
    19.             return best;
    20.         }
     
    eliteforcevn likes this.
  49. nglasl

    nglasl

    Joined:
    Oct 22, 2018
    Posts:
    7
    For someone else that may encounter the same thing I did, if you're having raycasts randomly missing - make sure you don't have thin convex mesh colliders. If you disable these from being convex, it solved the issue for me.
     
  50. darashayda

    darashayda

    Joined:
    Jun 27, 2020
    Posts:
    442
    THANK YOU! THE PROBLEM EVERYONE HAD STILL OCCURS AT 2022.X VERSIONS, BUT I ADDED

    Physics.SyncTransforms(); //HAS TO BE HERE
    Physics.Linecast(
    ....
    );

    AND INSIDE UPDATE AND ALL WORKS NOW....
     
Thread Status:
Not open for further replies.