I have a GUI.Box that I slide in from the side of the screen. How can I prevent mouse interaction from going to any objects under it (another GUI.Button for instance, or for that matter an GameObject)?
3 Answers
This is one of the annoying limitations of the built-in version of Unity's GUI. From most accounts I've seen, you have to do it yourself. Write an input manager that checks locations of mouse clicks and then decides to forward or not the clicks to whatever game systems you want.
Alternatively, use a different kind of input system that is based off of colliders. A popular one is NGUI.
-
\$\begingroup\$ I checked out NGUI, unfortunately (at least the free trial) has very poor performance. If there an example input manager I could look at someplace? \$\endgroup\$ Commented Jan 31, 2013 at 6:36
-
\$\begingroup\$ @Justin808 By all accounts I've seen NGUI is significantly higher performing than the built in GUI. The built in one (last time I checked) uses one draw call per GUI element. And the entire OnGUI chain is ran multiple times per frame (once per input event). With NGUI you can at least get your entire UI down to a single draw call. \$\endgroup\$– TetradCommented Feb 1, 2013 at 19:40
-
\$\begingroup\$ I've bought it to try it out. The unity player samples on the website were choppy on a 2nd gen MBA. I'm hoping that it was just a fluke. My 3nd gen MBA worked fine with them. \$\endgroup\$ Commented Feb 1, 2013 at 20:20
This could be done fairly simply and elegantly with GUI.depth and styling a GUI button as a box.
void OnGUI()
{
int prevDepth = GUI.depth;
GUI.depth = 0;
if(GUI.Button(someRect, "Some Button","Box"))
{
// Do something
Event.current.Use();
}
GUI.depth++;
// Do other stuff
GUI.depth = prevDepth;
}
If we have lots of objects in a scene it's often preferable to use a single script that handles the click Raycast itself instead of every collider object also having an void OnMouseDown()
callback.
When performing the Raycast ourselves we can check GUIUtility.hotControl
to see if an IMGUI UI control was just clicked.
Here is an example that performs such a raycast on an arbitrary number of collider objects in the scene and handles both having mouse clicks be blocked by Immediate Mode UI as well as Canvas-based UI (just for good measure).
Here is the source code: https://gist.github.com/JohannesMP/3d3882e6bd57e378412fa5d7d95d0c47
-
\$\begingroup\$ thank you very much for the contribution. I commented to you, that implementing the class you created works for me blocking the button that is created through the class, but my UI does not work. I invite you to watch the video (streamable.com/ighdu) to see if there is any possibility that you can give me your help. Regards \$\endgroup\$ Commented Dec 1, 2018 at 20:23