- Home /
How to check if player is hovering mouse over a GUI Box
Hey guys,
I was wondering, is it possible to simply check if the user is hovering their mouse over a gui box?
Thanks
-Grady
Is that GUI box created with code? Or just a GUI Texture?
Why are we reinventing the wheel? Unity already knows whether or not the mouse is inside the button, it changes colors, it 'activates' when 'pressed'/'clicked'... Why can't we access that information?
oh GR8 we can now convert answers to comments with 1$$anonymous$$ karma, ... did mistake by getting @SasugaShogun published, thought it was a question
thanks UNITY.
AND @SasugaShogun do not post an answer as a comment
Answer by DavidDebnar · Jul 05, 2011 at 01:36 PM
If you want to use a GUI Box or any other OnGUI element whose position and size is defined by a Rect, you need to realise that GUI elements are in GUI coordinates (0,0 = top-left), where Input.mousePosition is in Screen, or pixel coordinates (0,0 = bottom-left). This means you can do one of two things.
The first solution is the easier of the two - Events. Events and OnGUI are very tightly connected, so they share the same coordinate system.
var mousePosFromEvent : Vector2 = Event.current.mousePosition;
The second solution, if you for some reason don't want to use events, is to flip the y axis of Input.mousePosition.
var mousePosInGUICoords : Vector2 = new Vector2(Input.mousePosition.x, Screen.height - Input.mousePosition.y);
You can read about Input.mousePosition here. Or read more about Events here and here.
(thanks for robertbu for pointing out that pixel and gui coords don't match.)
function OnGUI () {
var rect1 : Rect = Rect(240,240,320,150);
var rect2 : Rect = Rect(0,0,300,500);
GUI.Box(rect1, "Rect1");
GUI.Box(rect2, "Rect2");
if(rect1.Contains(Event.current.mousePosition))
Debug.Log("rect1");
else if(rect2.Contains(Event.current.mousePosition))
Debug.Log("rect2");
else
Debug.Log("no rect");
}
---
If you don't mind using GUITextures, you can use the MonoBehaviour.OnMouseEnter() function.
function OnMouseEnter () { print("There is a mouse on me!"); }
David
Answer by chargedneuron · Jun 04, 2013 at 03:55 AM
I had to solve an issue like this today. I thought I would post my answer here so help others out...
On MouseEnter start a coroutine that waits whatever you want for a hover delay. Once the coroutine expires process your OnHover task; starting with a check to see that the mouse is within the rect before continuing. This will make sure we are still hovering as the timer expires. Upon MouseExit stop the coroutine.
float hoverDelay = 5;
Rect rectIcon; // The Rect for the GUI.Texture we are hovering over.
void OnMouseOver ()
{
StartCoroutine( "Wait", hoverDelay );
}
void OnMouseExit ()
{
StopCoroutine("Wait");
}
private IEnumerator Wait (float seconds)
{
yield return new WaitForSeconds(seconds);
if (rectIcon.Contains (Input.mousePosition)) {
//Do OnHover Stuff here. Or set a bool to trigger an event elsewhere.
}
}
This (and the other solutions on this page) will not work correctly assu$$anonymous$$g you are using GUI to display the box. 'rectIcon' will be in GUI coordinates. Input.mousePosition will be in screen coordinates. The "right" way to solve this position is to use GUI events and look at Event.mousePosition (which will be in GUI coordinates).
Respectfully - Perhaps you would be kind enough to provide a code example of the "right" way. Thank you.
#pragma strict
private var rect : Rect = Rect(200, 200, 150, 50);
function OnGUI() {
var e = Event.current;
if (rect.Contains(e.mousePosition))
Debug.Log("I'm in the box");
GUI.Box(rect, "Box");
}
Note OnGUI() is often called many times a frame. I don't know what you need this functionality for, but you may need to put additional conditions on the check if you only want it to fire once per frame.
Oh, and if you really need to use Input.mousePosition, the conversion between GUI coordinates:
var v3GUI = Camera.main.mousePosition;
v3GUI.y = Screen.height - v3GUI.y;
v3GUI can then be used in a Rect.Contains() call for a rect used for GUI output. But handling the mouse position using Event.current is a better way to handle the situation if you can.
I understand that part. $$anonymous$$y intention is to have an inventory item (as a GameObject.GUITexture) with a Rect. As the mouse enters the Rect I show the name of the Inventory Item with a GUI.Label at the mouse point. After 3 Seconds (via my coroutine) I replace the GUILabel with a detailed description of what the object is. If the mouse exits the Rect before, during, or after the Coroutine has fired I stop the coroutine to restart the 3 second delay.
I use the coroutine function to set a Bool that tells the OnGUI() function which GUI.Label to show.
As I understand your example you are suggesting I use the result of the Event.Current rather than the Rect.Contains functions?
Answer by DanjelRicci · Jul 05, 2011 at 01:32 PM
There is what you need here in the Unity guide: Rect.Contains
. Example:
//Check if the mouse is inside a Rect
var mouseInside = false;
function Update () {
var rect = Rect (0, 0, 150, 150);
if (rect.Contains(Input.mousePosition))
mouseInside = true;
else
mouseInside = false;
}
Just use a Rect wich represents your GUI box and you are done.
great answer, but you really can spare the if: var mouseInside = false; var rect = Rect (0, 0, 150, 150); function Update () { mouseInside = rect.Contains(Input.mousePosition)); }
Your answer
Follow this Question
Related Questions
GUI.Button on MouseHover 1 Answer
How to make a Hover event on GUI.Button 6 Answers
Detecting Mouse Over Using Tooltip 2 Answers
detect mouseover with grid buttons? 1 Answer
How To Get Current Mouse Position and have a GUI Box on right clicked 2 Answers