Hi, in my custom class I have a GUI.Button and I call its OnGUI method for each element of a list in a specific order to achieve the depth (the call order is draw order so my last called element gets on top and so do the buttons in each).
The problem is that GUI.Button, EditorGUI.EnumPopup and similar are getting activated on click in exactly opposite from the order they were rendered. If I have two buttons and one is under the other, I press the one drawn last but the one drawn first gets triggered. How to fix this?
Well, just found this question
It’s not a bug, it’s how immediate GUI systems work. Each “element” is on it’s own. OnGUI is called several times a frame for different “events”. Repaint is called every frame and makes the elements redraw itself in the order you invoke them. If a MouseDown even happens OnGUI is called again and your elements are invoked in the same order. That means the first element gets the event first.
GUI elements don’t “know” about other elements since it’s an immediate mode. The only ways to kind of order GUI elements are:
- setting GUI.depth which will only work between different in-game GUI scripts. So it only affects in which order different scripts are invoked. What’s inside OnGUI stays the same.
- Roll your own object based GUI system where each GUI element is an object with it’s own “OnGUI” method. Now the containing OnGUI method can simply reverse the invkoation order for mouse / keyboard events. However keep in mind that this won’t work with GUILayout since GUILayout saves the layouting information based on the order the elements got called. So the layouting information wouldn’t match the correct elements.
- using windows.
For the editor the best bet would be windows. Only one window can have the focus at a time. So if a window is on top of another window the one that has the focus will get the events first. Keep in mind that clicking into the area of another window will focus that one.
It’s usually the best to avoid overlapping GUI elements all together. If you need it in some rare cases you can use windows. The window callbacks are executed seperatly from the OnGUI code.
try switching there position, the one called first might be put on the top layer, and then every one called after gets below it, that is if it make a new layer for each, basically opposite of photo shop, the one that was made first is always on top, which it might be giving a value to that layer, so first layer = 0 secondlayer = 1, ect because it was first in line it is called first.
just my guess.
I have created two display methods, Active and Fake, inside fake I copied the whole gui code but instead each button and enumPopup I used a label, so from many buttons I created a situation where there is only one button at the time so no overlapping accours therefore bothside orders are equal and the bug is bypassed. Additionally I used a custom guistyle, and ObjectNames.Nicify that puts spaces before each capital in variables since that was being for focused elements and was not processed otherwise.