I can’t quite understand the behavior of Unity 2D when it comes to handling user input. Hope that someone can help me.
I have a number of sprites, and they may overlap. I can handle the drawing order of the sprites quite easily by using the “Sorting Layer” and “Order in Layer”.
In order to handle user input, I define 2d colliders for relevant objects. Those objects receive user input (OnMouseDown(), etc.)
Problems arise when sprites overlap. While the Sorting Layer is used for rendering, it seems that it is not used for delivering user input to the right (that is, topmost in the rendering order) sprite having a 2D collider.
So input seems to go randomly to one of the overlapping sprites, and the behavior does not even seem to be deterministic.
How can I direct the input to the right (topmost) sprite game object?
Sorting Layer is related with rendering. Although you are developing a 2D game, actually you are working on a 3D system. Your sprites are on same index “Z” in Z layer. User touches and moues touches does not have a “Z” index. I mean it’s 0. You can use “Z” value of sprites to determine which stands front and which stands at back. Position of camera is important too.I recommend you to switch to 3D view and see the order of sprites as you play with “Z” values. Here is a code script that i use to give “z” index to my touch:
Following code moves the touch point to -10 in “Z” and tiggers a check from -10 to +10 (due to given length: 20)
private bool IsDialogHit (Vector3 touchPosition)
{
touchPosition.z = -10;
//First let's check if there is an ui element. In that case return null. It's handled by ui.
RaycastHit2D uiHit = Physics2D.Raycast (touchPosition, Vector2.zero, 20, _onlyUiMask);
return uiHit.collider != null;
}
Also you must be sure that Screen Positions are translated to World Positions by (_main the the Main Camera we use; it changes the position in screen to our world point system):