I assume you are specifically asking how IPointerDown and Physics2DRaycaster works. Not Physiscs2D “raycasting” methods which there are there are 3x3(normal, All, NonAlloc) (OverlapPoint, Raycast, GetRayIntersection), don’t use Physics2D.Raycast with 0 length for pointer checks, that’s for rays within 2d plane, not for rays coming from camera, use OverlapPoint or maybe GetRayIntersection instead. The priority for OverlapPoint is described in docs, supposedly it prefers lowest Z value after filtering out by other conditions.
Back to IPointerDown and Physics2DRaycaster. Luckily for you both of them are within uGUI for which all the source code is available. The links I will be giving will be to slightly older version in the public repository, but I doubt things have changed too much. If you want to be sure you can view the actual latest code in Library/PackageCache/com.unity.ugui folder of your project.
So the overall Call sequnce is something like this: InputModule → EventSystem.RaycastAll → Physics2DRaycaster.Raycast → Physics2D.GetRayIntersectionAll .
Physics2DRaycaster is using reflections to call GetRayIntersectionAll instead of doing it directly, but that shouldn’t change anything.
The order for Physics2D.GetRayIntersectionAll isn’t clearly defined in docs although since it is a 3D ray I would expect it to be sorted by Z, just like OverlapPoint, but that doesn’t really matter due to stuff that happens afterwards.
After gathering all the raycast hits from all the raycaster modules Event system sorts them using RaycastComparer . Due to this sorting order returned by Physics2D.GetRayIntersectionAll almost doesn’t matter . The ordering established by RaycastComparer is based on many factors:
-
raycast module (for stuff like overlay canvas stuff being on cameras and the order between multiple cameras)
-
sorting layer
-
sorting order
-
depth → doesn’t seem to be set by Physics2DRaycaster
-
distance → seems to be somewhat useless since it uses ```
Vector3.Distance(eventCamera.transform.position, m_Hits**.point)**
-
wherem_hits.point``` is Vector2d so the Z position is thrown away. Will differ between objects only based on 2D distance from camera center*
-
- index → the order returned by GetRayIntersectionAll, only used if everything else is identical*
While these sorting conditions are somewhat similar to conditions for drawing order sorting there are few differences. 2D sorting axis is completely ignored. When using SortingGroup result will likely be mess unless you have set sorting layers within sorting group to match with the global sorting order in which case you wouldn’t need sorting groups. SortingGroups are also likely to be used in combination with sorting axis (which isn’t taken into account). Even if you attached physics collider to sorting group instead of sprites within sorting group it would still not work since Physics2DRaycaster only takes sorting layer and sortingOrder only from SpriteRenderer, TilemapRenderer, SpriteShapeRenderer. Due to the same reason it will also not take into account sorting layer for noncanvas TextMeshPro text component or any other component which supports sorting layer/order but isn’t one of the 3.
Assuming with this knowledge you still can’t reorganize the structure of your game to get desired clicking priority I see two major options:
A) Don’t use IPointerDown… interfaces for noncanvas objects. Call Physics2D.OverlapPointAll yourself and choose correct result based on your own rules. Most annoying part with this is ensuring that clicking on overlay canvas doesn’t result in clicks on non canvas objects (whole Raycaster/EventSystem/InputModule setup gives that for free). One hacky workaround I have used is placing a transparent rectangle behind all the UI to serve as pointer click receiver, and using pointer events received by that instead of querying raw mouse input API .
B) Customize the sorting order within Unity. Doesn’t seem like you can easily override the sorting order within EventSystem by subclassing it. But you could create your own version of Physics2DRaycaster (it’s only 100lines of code) and set better values within RaycastResult. It would be even simpler if you threw out the part that deals with various cases of maxRayIntersections and the reflections for accessing Physics , since in your game you can probably make reasonable assumptions about both. Adding basic support for SortingGroup and TextmeshPro shouldn’t be difficult, it might even possible to support sorting axis (with some limitations) by storing the position along sorting axis either in distance or depth fields.