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

Bug OnCollisionEnter works ~30 percent of the time

Discussion in 'Scripting' started by thel33tdood35, Jun 24, 2023.

  1. thel33tdood35

    thel33tdood35

    Joined:
    Jan 30, 2021
    Posts:
    9
    I have a very simple scene, where the player is able to click to fire a bullet. this bullet has a box collider that is slightly bigger than the bullet itself, and no rigidbody. There are also several walls, which are just boxes with colliders and rigidbodies, not kinematic, not static, and neither are triggers. OnCollisionEnter works between the boxes and the bullets, but only if the boxes are large enough. And even when they are, it still only works ~30 percent of the time.

    now, I know that if a collider is going fast enough, the collision might not be detected, but these bullets are moving very slowly. What's more is that these bullets were colliding perfectly moments ago, before I changed an unrelated script.

    upload_2023-6-24_9-45-7.png
    (this bullet went right through the box.)
     

    Attached Files:

  2. CodeSmile

    CodeSmile

    Joined:
    Apr 10, 2014
    Posts:
    3,899
    Could it be that the bullet gets spawned inside the other collider? Not sure if physics will simply ignore the collision in such a case.
     
  3. thel33tdood35

    thel33tdood35

    Joined:
    Jan 30, 2021
    Posts:
    9
    no, even when standing far away from any other colliders, the problem still persists. the player character does not have a collider either, so that can't be it.
     
  4. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,563
    I'll guess that you are mis-using the physics system but you posted no code.

    With Physics (or Physics2D), never manipulate the Transform directly. If you manipulate the Transform directly, you are bypassing the physics system and you can reasonably expect glitching and missed collisions and other physics mayhem.

    This means you may not change transform.position, transform.rotation, you may not call transform.Translate(), transform.Rotate() or other such methods, and also transform.localScale is off limits. You also cannot set rigidbody.position or rigidbody.rotation directly. These ALL bypass physics.

    Always use the .MovePosition() and .MoveRotation() methods on the Rigidbody (or Rigidbody2D) instance in order to move or rotate things. Doing this keeps the physics system informed about what is going on.

    https://forum.unity.com/threads/col...-unity-physic-rigidbody.1216875/#post-7763061

    https://forum.unity.com/threads/oncollisionenter2d-not-being-called.1266563/#post-8044121

    If you post a code snippet, ALWAYS USE CODE TAGS:

    How to use code tags: https://forum.unity.com/threads/using-code-tags-properly.143875/
     
    angrypenguin likes this.
  5. thel33tdood35

    thel33tdood35

    Joined:
    Jan 30, 2021
    Posts:
    9
    I'll try this, but what's confusing me is that my bullets, even without using movePosition, were colliding just fine, before I changed an unrelated script.

    EDIT:
    movePosition is for rigidbodies, which my bullets are not. the bullets have colliders, but the walls have rigidbodies, and are completely stationary.
     
  6. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    3,495
    That is your actual issue. ONLY rigidbodies which are awake can detect collisions. Colliders must NEVER be moved without a rigidbody. Colliders without a rigidbody are supposed to never move at all and are usually included in the world / scene collider. When a rigidbody is awake it could detect / react to overlaps with other colliders. However when a rigidbody isn't moved for some time / goes below the sleeping thresholds it falls asleep. When a rigidbody sleeps it can not detect collisions and is not simulated anymore. Kinematic rigidbodies can't detect collisions either. However they can wake up other non kinematic rigidbodies when they overlap so collisions are handled correctly. See the docs for more information.

    In general anything that has a collider and moves has to have a rigidbody. Things that do not move at all don't need / should not have a rigidbody. Especially read the definition of "static collider". The "Collision action matrix" may be a bit misleading because it doesn't specify which of the two objects is moving or if the rigidbody is sleeping or not. They just made the matrix symetrical at the diagonal, even though moving a static collider into a sleeping rigidbody is not even bad for performance but also should not cause a collision. Sometimes your rigidbodies may wake up due to some other even so it may detect collisions. However bullets could never use continuous collision detection if the bullet doesn't move with the physics system.
     
    Unifikation, angrypenguin and zulo3d like this.
  7. thel33tdood35

    thel33tdood35

    Joined:
    Jan 30, 2021
    Posts:
    9

    the bullets still collide sometimes though, and if the walls never move I assume they'll either stay permanently asleep or permanently awake. Plus, and I keep saying this, they were colliding fine before my scripts refreshed after changing a different script.
     
  8. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    15,503
    Is "sometimes" enough?

    The others have it right. You're not using the system as it's designed to be used, and intermittent results are exactly what I'd expect from what you've described. Yeah, somehow the internal static collision data update results in collisions getting detected "sometimes", but it'll never get better than "sometimes".

    To get from "sometimes" to "reliable", you need to start using the system the way it is designed and optimised to be used. Rigidbodies go on the things which move.

    Furthermore, even if this did work as it was set up, for bullets there's a good chance you're going to need continuous collision detection, so that fast moving objects don't skip through small or thin things. That can only be applied to Rigidbodies.

    It's a red herring. Things which work intermittently often give the impression of being "fine" for a while.

    I wouldn't assume, I'd debug it and find out. It's entirely possible that there was something keeping your Rigidbodies awake before, and now it's not.

    I've had cases before where things worked specifically because of what I was doing to test them. Then they "break" later, and the fact is that they were always broken, and my testing just happened to miss it. Then later something unrelated seemed to break it, where what was really happening is that I was using it differently.
     
  9. thel33tdood35

    thel33tdood35

    Joined:
    Jan 30, 2021
    Posts:
    9
    the statistical chance that thousands of bullets would nail a 1/3 die roll, and then suddenly stop nailing that die roll RIGHT after a script change is cosmic, and I wouldn't just chalk it up to chance.

    I'll try again putting rigidbodies on the bullets, but last time it resulted in weird behaviour.
     
  10. Ryiah

    Ryiah

    Joined:
    Oct 11, 2012
    Posts:
    20,082
    Weird behavior says to me that you're trying to work with the physics engine using non-physics, but there's no way to know without seeing the settings for the colliders, rigidbodies, and the scripts involved.
     
    Yoreki and angrypenguin like this.
  11. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    15,503
    You're getting weird behaviour now. Your resistance to using the system as it's designed and documented is irrational.

    You're not going to get consistent and correct behaviour until the whole thing is configured correctly. That takes time and learning the first time. And yes, some of the results from even minor misconfiguration can be confusing initially.

    Including the "unrelated" one that supposedly stopped it all working.
     
    Yoreki and Ryiah like this.
  12. JoshuaMcKenzie

    JoshuaMcKenzie

    Joined:
    Jun 20, 2015
    Posts:
    897
    Not as cosmic as you may expect.

    Unity usually isn't just compiling that one script. its recompiling and loading entire domains. In some cases Visual Studio can get prompted to auto-save all scripts, past the one script you did change, all depending on how to tried to compile. in fact it may be that one unrelated script failing (or not failing) that ultimately changes the branching of some higher level script which can change your physic code form getting called. There can even be 3rd party plugins that don't properly reset on domain reloads and as such even they fail to properly reset (and being a 3rd party plugin it may even be failing silently).

    These types of bugs aren't common, but they happen too often to be "cosmic".

    either case check the easy steps first, look for colliders (on BOTH objects), check that the bounds area matches the geometery enough, look for rigidbodies, check the collision matrix, check CCD, also try raycasting to debug that you can hit the objects with your rays.

    and if it comes to it, close unity and relaunch just to be sure everything properly reloaded
     
    Last edited: Jun 27, 2023
    Chubzdoomer and angrypenguin like this.
  13. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    15,503
    Indeed.

    On top of that, it's almost certain that what was actually happening is different to what was perceived to be happening. I don't for one second believe that "thousands of bullets [hit] a 1/3 die roll", let alone the rest.

    We can only go by what we've been told, and all we've been told is that is that they were hitting for an unknown reason, then there was an unknown change to an "unrelated" script, and then it was noticed that they weren't hitting any more. There is oodles of room between those unknowns and the unspecified time spent on "unrelated" stuff for a perfectly non-cosmic reason to be wandering around.

    To add to Joshua's examples, changes made in play mode are another common one.
     
  14. KillDashNine

    KillDashNine

    Joined:
    Apr 19, 2020
    Posts:
    449
    - Put all physics code inside FixedUpdate()
    - Don't move or rotate transforms but instead apply physics forces to them
    - Try different interpolation settings on your Rigidbody
    - Check Project Settings->Physics, look at the settings on top of the list