- Home /
UnityGUI click event
I've created a UI using UnityGUI. When I click on either GUI.Button or GUI.Box the click is processed by objects on the scene.
if (Input.GetKeyDown ("mouse 0")) {
Ray ray = Camera.main.ScreenPointToRay (Input.mousePosition);
if (Physics.Raycast (ray, out hit)) {
// ...
}
}
I need to determine the fact, that the UI was clicked on. In case of GUI.Button I can check wether GUIUtility.hotControl != 0. GUI.Box doesn't modify GUIUtility.hotControl.
What is the common solution?
Answer by FadeToBlack · Jun 03, 2012 at 10:23 AM
just now i found the next solution (i use it in dragging camera routine):
if (Input.GetMouseButtonDown(2) && GUIUtility.hotControl == 0) {
pos = cursor.getPos(false);
drag = true;
}
this condition ignores mouse down when we click on gui elements
for this answer. It seems if hotControl = 0 no elements of GUI are active.
Thanks all.
Answer by Bunny83 · May 24, 2011 at 10:59 AM
Ahhh, finally i got your problem :D. To sum up:
You have a GUI on your screen
You use the above posted raycast to interact with GameObjects in your scene
You don't want to interact with objects that are behind the GUI when you click on the GUI.
I think that's your problem, right? It's really hard to get that out of your question.
You can simply check if the mouse is inside the Rect of your box/window. If you use GUI.Box just use the Rect you're using to create the Box. If you use GUILayout you can use GUILayoutUtility.GetLastRect to determine the Rect. To check if you are over the GUI use Rect.Contains with the mouse position (inside OnGUI use Event.current.mousePosition).
//C#
bool overGUI = false;
void OnGUI()
{
Rect guiRect = new Rect(10,10,100,100);
GUI.Box(guiRect);
if(GUI.Button(new Rect(20,20,80,30),"Click Me"))
{
// clicked
}
if (Event.current != null && Event.current.isMouse)
{
overGUI = guiRect.Contains(Event.current.mousePosition);
}
}
or with GUILayout
bool overGUI = false;
void OnGUI()
{
GUILayout.BeginVertical("", "Box"); // style it like a Box
if(GUILayout.Button("Click Me"))
{
// clicked
}
GUILayout.EndVertical();
Rect guiRect = GUILayoutUtility.GetLastRect();
if (Event.current != null && Event.current.isMouse)
{
overGUI = guiRect.Contains(Event.current.mousePosition);
}
}
Now you can check the boolean if your over the GUI or not ;)
ps. I wrote that from scratch so it's not checked for syntax errors ;)
You are absolutely correct with the definition of the problem. Thank you.
Your solution is pretty obvious and it doesn't seem to be applicable in a couple of cases including $$anonymous$$e: 1) I have serveral boxes. Iterate over a collection of Rects? Hmmm. 2) $$anonymous$$y boxes are not rectangular. They have alpha-images as background.
Well, from Unity's view all GUI elements are rectangular. Custom shapes are a bit tricky. The only way (if that is important) to get a perfect result is to use a $$anonymous$$eshcollider with the shape of your GUI and raycast against it ;). If rectangles are ok you can turn your "boxes" into windows. As far as i know windows work with GetNameOfFocusedControl. $$anonymous$$aybe the box works as well, i never tried it ;) http://unity3d.com/support/documentation/ScriptReference/GUI.GetNameOfFocusedControl.html
Answer by Owen-Reynolds · Feb 10, 2012 at 09:59 PM
This is what worked for me. It ignores the first and all clicks in a GUI.textField, and sees even the very first click outside of one:
if(Input.GetMouseButtonDown(0) && GUI.GetNameOfFocusedControl()=="") {...}
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Turns out the rule about not using GUI stuff except in OnGUI doesn't apply to getNoFC. It can be examined from Update. You have to be sure to set names -- ex: GUI.SetNextControlName("b");
-- in front of all your focusable controls (you can be lazy and give them all the same name.)
I've read hotcontrol and focusedcontrol solutions to this problem countless times but this is the first time I've seen a mention of being able to name your own controls X_X
Documentation needs a REHAUL.
edit: Well turns out that is in the documentation for GetNameOfFocusedControl, just that I hadn't visited that page of the docs yet. Not negating the fact that the docs need work, just that I spoke too soon this time
Answer by arlinon · Dec 29, 2013 at 02:48 PM
I tried to use above methods and few other but couldn't get what I really want.
I ended up making a rect for where I see the scene from and raycast through. Game just checks whether the scene rect contains mouse click as explained in here http://docs.unity3d.com/Documentation/ScriptReference/Rect.Contains.html
Answer by vikingfabian-com · Aug 28, 2014 at 12:37 PM
This works for editor GUI
public static bool LeftMouseUp()
{
return Event.current != null && Event.current.type == EventType.MouseUp && Event.current.button == 0;
}
Your answer
Follow this Question
Related Questions
Bad UI resolution with Uni2D 0 Answers
Changing the target of a button that takes a gameobject as a parameter? 0 Answers
Setting negative value for rectTransform sizedelta !!! 0 Answers
Unity 4.6 scrollbar defaults to wrong position with grid layout 1 Answer
How to display UI elements in front of the gameObject? 1 Answer