- Home /
If I have a button over my 3d world, how can I detect if a mouseClick was in the world or not?
NOTE...
This QA is extremely out of date. Regarding this annoying disaster in Unity, for 2015...
My game is a 3d world. From time to time I want to display buttons ontop of the 3d world. How can I detect mosueclicks in the 3D world? If I use Input.GetMouseDown(), I also react on buttonclicks, which I don't want.
So you want a GUI-like interface which will be transparent to mouse clicks, like a chat box, right? Nowadays that's not difficult to do at all. :)
Answer by AngryAnt · Oct 21, 2009 at 09:13 AM
GUI receives mouse events one frame before Input does - you can use this fact to detect whether or not a mouse event was consumed by GUI when you're checking for mouse events in Input.
if (!GUIDidConsumeMouseDown (0) && Input.GetMouseDown (0))
{
Debug.Log ("Click in the 3D world");
}
And the pseudocode logic to detect GUI event consumption:
- OnGUI:
- GUIDidGetMouseDown (Event.button) = Event.current.Type == EventType.MouseDown;
- // The rest of your GUI //
- GUIDidConsumeMouseDown (Event.button) = Event.current.Type == EventType.Used ? GUIDidGetMouseDown (Event.button) : false;
MonoBehaviour.OnMouseDown and friends automatically handles this - if you only rely on this functionality, you do not need to track GUI event consumption.
Answer by Ent · Jun 11, 2010 at 10:21 AM
Hi, been reading through some other postings and gathered some interesting things together that may help some other people reading this and needing a more complex solution for different reasons and using a window below the GUI.
// Boolean for when mouse is over window
var onMouseOverMenu : boolean = true;
// Creation point of window
var windowRect : Rect = Rect (20, 20, 200, 300);
// Rect of window. Can also be windowRect if the creation point is not needed anymore
// after the creation of the window
var windowRectBox : Rect;
function Update(){
//if you have multiple GUIs you could use something like: // //Dont forget to change onMouseOverMenu to a boolean Array and to refer to this script. // var isOnMouseOverMenu : boolean = false; // for (var oMOMPtr : int in onMouseOverMenu) // if(onMouseOverMenu[oMOMPtr]==true)isOnMouseOverMenu = true; // if(isOnMouseOverMenu){ // //... enter script here // }
if (onMouseOverMenu) { // ... enter script here }
if (!onMouseOverMenu) { // ... enter script here }
}
function OnGUI () { windowRectBox = GUI.Window (0, windowRect, WindowFunction, "My Window"); }
function WindowFunction (windowID : int) { // Draw any Controls inside the window here
// Sets a Rect to the size of this window. var curBox : Rect = Rect(0,0,windowRectBox.width,windowRectBox.height);
// Checks if the mouse is inside of this Rect. // Due to a Window setting the Event.current.mousePosition to the position refering //to this window, our Rect starts at 0,0 and not at the creation point of this window. // Using Input.mousePosition is also a problem due to the creation of a GUI Element being // refered to from a corner point of the screen (default top left), even if created with // a Rect and that a Rect or Input always starts from the bottom left corner. // So if using xyzRect.contains(Input.mousePosition){} and creating a window at xyzRect, // you will notice that that the xyzRect.contains is not the same position as the window // created in xyzRect, even thou these are the same Objects. For this to work, // you would have to create all GUI elements from the bottom left corner. if(curBox.Contains(Event.current.mousePosition)){ Debug.Log("Mouse in Menu at " + Event.current.mousePosition); onMouseOverMenu = true; } else if (onMouseOverMenu == true) { onMouseOverMenu = false; }
// ... enter GUI here
}
e.g. if you have an onScreenDisplay wanting to show the distance to an object inside this screen: // place in Update()
//Where the mouse clicks var ray = Camera.main.ScreenPointToRay (Input.mousePosition);
if (onMouseOverMenu) { // ... enter script here // ... only cast on gameObjects behind this window (or Rect)
//Do a raycast from camera in direction of ray,
//with a distance 100.0 and return hit.
if (Physics.Raycast (ray, hit, 100.0)) {
//hit.distance is the distance to the first collider.
distanceToGround = hit.distance;
//This draws a line, that shows the ray, in the editor.
Debug.DrawLine (ray.origin, hit.point);
}
}
Answer by Veehmot · May 30, 2012 at 10:08 PM
Use GUIUtility.hotControl
.
Worked like a charm for me!
I used something like: if (GUIUtility.hotControl == 0) { //click is not on gui }
This does not work with certain GUI controls (Ie: GUI.Box).
Answer by gnoblin · Oct 20, 2009 at 05:33 PM
Use OnMouseDown() function in a script hanging on your GameObjects.
Answer by ben · Mar 15, 2011 at 12:04 PM
use events such as mouse position and click count inside GUI button
var gu : GUIText; var aa = 0 ; var aaa : String;
function OnGUI(){
var e : Event = Event.current; Debug.Log(e.mousePosition);
if(aa==1){
GUI.Button(Rect(20,100,50,50),aaa);
}
if(GUI.Button(Rect(20,30,100,50),"Button")){
if(e.mousePosition.x <= 120){
var ee : int = e.clickCount;
var eee : String = ee.ToString();
aaa = eee;
print(eee);
aa =1;
gu.guiText.text = eee;
}
}
}
Your answer
Follow this Question
Related Questions
gui list problem 2 Answers
Best practices to listen for inputs and show GUI? 0 Answers
Updating GUI text with GetButtonDown? 1 Answer
how to input words from array to GUI? 0 Answers
Determining GUI button pressed 2 Answers