- Home /
GUI.Button render order vs click order.
We have noticed something curious which we think is the core of several issues concerning 2D artifacts on our games. I wanted to attach a screenshot but apparently the attach image thing is not working right now. Anyway... the attached script draws three squares (GUI.Buttons) on the screen that are staggered and partially overlapping. Starting top left and rendered in the back is a white square, then a yellow square and in the front on the bottom right is a red square.
What we have noticed is that if you click on any button in an area that has a button behind it then the rear button gets the event. For instance if I click on the top/red button area where the others intersect behind it, the bottom/white button gets the click. If I click the middle/yellow button where the bottom/white button is underneath it, the bottom/white button gets the click.
If you click the middle/yellow (or any other) button where there is nothing behind it, it works as expected. Other wise it works completely counter intuitive to any other GUI system I have worked on. Basically it looks like the clicks get intercepted with the render order.
Is there a reason for this in design or is this a feature (or a bug) in the Unity GUI system? Is there a workaround or hack that may be employed to make this work somewhat is expected?
Here is a simple script demonstrating what I am talking about:
using UnityEngine;
using System.Collections;
public class GuiClickThroughTest : MonoBehaviour {
void OnGUI()
{
GUI.color = Color.white;
if (GUI.Button(new Rect(450, 100, 200, 200), "A WHITE button"))
{
Debug.Log("WHITE button pressed " + Event.current);
}
GUI.color = Color.yellow;
if (GUI.Button(new Rect(500, 150, 200, 200), "A YELLOW button"))
{
Debug.Log("YELLOW button pressed " + Event.current);
}
GUI.color = Color.red;
if (GUI.Button(new Rect(550, 200, 200, 200), "A RED button"))
{
Debug.Log("RED button pressed " + Event.current);
}
}
}
Answer by Bunny83 · May 27, 2011 at 03:43 PM
Sure, that's the normal behaviour of an immediate GUI system. It processes all your GUI elements in the order you create them. So if the first one catches an event noone else will be able to use the event. The drawing happens in the same order, that's why the last object is drawn on top of everything else.
Because of this the event-handling first reacts to the bottom-most elements. The only GUI element that works different is a GUI.Window.
It isn't drawn immediately. All windows are collected and get drawn in the current z-order after the OnGUI function is finished. The input handling is executed reverse. That works only for windows because they provide a delegate callback for their content. Windows change their z-order automatically when they got focused.
Normal GUI elements should not overlap to prevent such misbehaviour.
I'm not sure why the buttons should overlap? Is it because of the margin/padding? you can set them to 0 to put the buttons seemless together. Take a look at GUISkin (scripting ref)
"Normal GUI elements should not overlap to prevent such misbehaviour." I sort of felt like that was going to be in the response. For a normal desktop 2D app I would totally agree with you. Obviously, drawing the "Submit" over the "Cancel" button makes no sense. In the Unity world (and probably for other game engines) I would somewhat disagree. The use case and applications for "buttons" is greatly expanded in this case.... we use buttons for all sorts of diverse things that would not really be thought of as a "2D button" in the traditional sense. I think of it more as a control that receives clicks and sometimes the our usages are such that those controls overlap. Base on your answer I suppose we will have to account for this. Thanks for your answer.
I'm not sure I fully understand. Say you have an object in 3d world that you want to be 'clickable' just add a collider and use On$$anonymous$$ouseEnter
Well, i understand that some special GUI layouts will need overlapping elements and that's a problem that isn't covered by Unity. You can of course split the visual button from the logical button by wrapping them in your own classes. That way you can seperate the input-handling from the visual appearance.
The GUI system is not perfect and it's almost impossible for such a system to cover all possible setups. Because it's quite simple you can easily extend the functionality.
Answer by jahroy · May 27, 2011 at 04:44 PM
Here's a question that I asked (and answered) about drawing GUI controls on top of each other:
http://answers.unity3d.com/questions/59898/how-to-draw-gui-controls-on-top-of-each-other.html
Answer by nicepainkiller · Apr 19, 2016 at 05:01 AM
this same question: ask solution http://answers.unity3d.com/questions/1173148/guilayouttextfield-do-not-work-on-guibutton-1.html
Your answer

Follow this Question
Related Questions
check if 'B' key is being pressed while clicking in Editor window 3 Answers
Raycast against UI in world space 4 Answers
How to wait click on button in my MessageBox analogue? 1 Answer
apply click event in test 0 Answers
On Gui Object Click 1 Answer