the problem of rigidbodies hijacking colliders and meddling with things not related to what rigidbodies should do strikes again:
Create a 2D project. Attach some 2D colliders to gameobjects with sprite renderers. All is well.
OnMouseDown (and similar events) are consistent with raycasts and rendering:
If you click a position where multiple colliders overlap, the one whose sprite is rendered frontmost gets the events.
Now attach a rigidbody2D to the gameobjects. Chaos reigns.
If you click a position where multiple colliders overlap, some one gets the events.
I was not able to identify which one. It’s certainly not the one with the frontmost sprite. Z-Axis seems to have something to do with it sometimes. Order in the scene hierarchy is not it. Of course parent-child-relationships have interesting interactions with rigidbodies but this issue happens without any parenting happening.
Note that the mouse and it’s callbacks are part of the UI system and that physics knows nothing about rendering or its order nor is it involved in the UI system of which the mouse callbacks stuff is part of. The physics systems doesn’t use Z because it’s a 2D physics system. You can change the Transform.position.z to whatever you like and it makes no difference to physics nor does render sorting.
It’s certainly not a bug with 2D physics. Any sorting you might be seeing would be in the UI system but AFAIK they use the Physics2D/3D raycasters which is a script that just does raycasting.
The nearest thing that physics provides is GetRayIntersection but all that does is perform a 2D raycast (3D projected in 2D) then sorts the results by the Z position on the Transform. This though doesn’t relate to other render sort orders because it knows nothing about them.
I’m a 2D physis dev and I’ll be honest, I’m not sure what the real solution to this is.
I am actually glad, that z position has nothing to do with it. I also totally understand, that physics and UI are different systems and should stay agnostic of each other.
But it is exactly for that reason, that adding a physics-related component should not change the mouse callback behaviour.
Mouse-Events on non-UI gameobjects (2D Collider + Sprite) are a supported and very useful feature. They work perfectly when using 2DColliders and Sprite Renderers on the same game object. Their behaviour does not only change when adding a rigidbody2D but seemingly becomes random/undefined. (Since rigidbodies interact with 2DColliders I guess something happens here that irritates Mouse-Events)
Thank you for your honesty. However, in my opinion at least, a simple (yet maybe not easy to perform) solution would be to make mouse-event behaviour with and without attached rigidbodies consistent.
Basically I’m not asking the physics to bother with rendering-orders, I’m asking it to NOT meddle with mouse-event orders.
But as you’ve said you understand, Physics doesn’t and cannot do this at all. It cannot “meddle with mouse-event orders”. It’s more likely that the order of the returned results is undefined (unsorted) and most likely in the order returned by the query the UI system is doing. Changing physics can change that order. For instance, performing an OverlapPoint for multiple results returns them in an undefined order unlike raycast which returns them in a sorted order. The order coming from the physics system is related to where objects are in an internal structure.
There’s simply no way the physics system can change these results. Even physics queries don’t care if the colliders are Static, Kinematic or Dynamic. The UI system itself wouldn’t know either so it’s most likely unordered and ordered from the original returned results. Maybe the UI is just using the first item, not sure.
I just took at look at the UGUI event system code for this and it uses GetRayIntersection which returns results in an ordered list (they are ordered by Z only which isn’t going to necessarily be render order). This will NOT change according to whether there’s a Rigidbody2D attached or not. Even if it did (which it doesn’t), you’re saying the order is render order which again isn’t something the physics system knows about so it’s UI related. Also note, that there’s a body even if you don’t specify one. If you’re seeing differences then it’ll be in the UI code somewhere although I have no idea how that part works. The code certainly seems to gather all results and produces an event for each. As to how those events are then sorted, I don’t know but if there is sorting then it will not be then related to physics.
To reiterate though, this is neither a 2D or Physics feature so you might be better off discussing this on the UI forums which the UI team monitors.
You are totally correct, I did very sloppy testing.
Apparently (based on a little less sloppy testing) if the Z-coordinate results in a draw the creation-order of the objects comes into play (which happened to coincide with rendering-order in my initial testing.) However adding a rigidbody (or probably a lot of other things) will change that order.
There is no bug, neither in physics nor UI.
However, the fact that OnMouseDown prioritizes 2D-Colliders based on Z-axis and concludes draws in a semi-random fashion is… unintuitive.
Thank you very much for your help, this can now be closed.