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?

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

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 :wink:

ps. I wrote that from scratch so it’s not checked for syntax errors :wink:

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 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 Unity - Scripting API: Rect.Contains

This works for editor GUI

public static bool LeftMouseUp()
{
    return Event.current != null && Event.current.type == EventType.MouseUp && Event.current.button == 0;
}