GUI.Button() hover detection?

Is there a way to determine from the GUI.Button() call whether the mouse is hovering over the button? I could, of course, explicitly test mousePosition against Button’s Rect argument, but that would be cumbersome when using groups.

I know that the background image and text color can be set for button hovering via GUIStyle, but I want to play an audio loop when hovering.

Thanks.

You need to check the mouse position against the button’s rect.

It’d be helpful if all the GUIStyle On methods had a property for an optionally-looping sound clip. Every published game GUI I’ve worked on was riddle with custom sounds. Should go in GUIStyleState?

I’ve been thinking something along those lines myself - just not sure exactly how to do it while keeping the number of parameters down - I can see having stuff like audioClip, looping (bool)

But I’m not quite sure how to implement it in practice… I’m on it, though - so it’ll be there.

Rather than checking the Rect of a button, would it be possible to check if the buttons GUI Style is in the hover state?

There must be some Rect checking already done to activate the Hover style, so it seems more effective to piggyback off this.

Thx
Shaun

Thinking that since there are already a huge number of parameters, what is a few more for this important feature?

Great to hear. :slight_smile: Any version ETA?

Yes - an ETA would help. I’m just about to get jiggy with a GUI overhaul - hope I’m not going to need to do it again 1 month later…

PS. this thread should be in the Unity GUI section

never. But since I’m still considering what would be the best way to do it, a good guess is “not in the immediate future”

I second the desire for a generic “onMouseOver” call, piggybacked off the hover state, if possible. Or at the very least an if(hover == true) that can be called.

Something similar to GUI.changed would be great for detecting hovering. For example:

GUI.hover=false;
if (GUILayout.Button("Foo")) { Foo(); }
if (GUI.hover) infoString="foobar";
GUI.hover=false;
if (GUILayout.Button("Bar")) { Bar(); }
if (GUI.hover) infoString = "barfoo";

GUILayout.Label(infoString);

For convenience, there could also be GUI.lastControlHover. A generic GUI.hover would be useful though for things like checking for hovering over a large group of buttons…

I just wanted to let the Unity developers know that I too miss the feature. It is quite essential for creating custom GUI interfaces.

I made a simple hovering detection for our last game. It’s not optimal but it works. I have included a simple example below

var hover : String;

function OnGUI(){
	GUI.Button (Rect (10,10,100,20), GUIContent ("Button 1", "Button 1"));
	GUI.Button (Rect (110,10,100,20), GUIContent ("Button 2", "Button 2"));
	hover = GUI.tooltip;
}


function Update () {
	if(hover=="Button 1")
	Debug.Log("Hovering Button 1");
	
	if(hover=="Button 2")
	Debug.Log("Hovering Button 2");
}

Nice going Claus! =)

Finding that creating a boolean based on the length of the tooltip returns both true and false every frame for when hovering over a button with a tooltip…

I suppose this is due to how tooltips are created. Is there a reliable way of getting such info?

Maybe checking like this will help

if(Event.current.type == EventType.repaint) {
  
  Code that is only execute once on the gui function passes.

}

Thank you Marc, that is very helpful.

I’ve got a suggestion how you could get all the info anyone could ever want from a GUI Element, without adding more parameters or such.

Instead of returning a string (e.g. Text-Elements) or a bool (e.g. Buttons), return Wrapper Classes, that can implicitly be cast to string or bool. This would guarantee backwards compatibility.

When not cast down these classes could include all kinds of variables, storing the state of the Element.

We use GUILayout for lots of stuff. With it, you can pass in things such as GUILayout.Width, etc… why not just add another one called GUILayout.Report(ref OutReport), and when present, allow the internals to give all the info back…

For GUILayout, that would likely be the ‘result’ rect of the layout, item state, hovering/focus id, etc.

Something similar may be possible for non GUILayout, I haven’t thought much about it.

My company has finally closed a source-license deal, so I’ll be putting forward lots of tweaks changes useful/important to our work (for addition to the Unity trunk), and this is one of them…

Dave

1 Like

Redacted

The only reason anyone is using the GUI/GUILayout is for a quick-and-dirty test or demo UI. The main benefit is not needing to pull in an external GUI library.

Nearly a decade since this thread was started and people (me) are still being bit by there being no way to tell if the mouse is over a GUI element. GUILayoutUtility.GetLastRect doesn’t actually seem to work–it’ll give the size of a low-level element (eg. a button), but it won’t seem to give the size of a layout container (eg. an entire GUI box), just logging “cannot call GetLast immediately after beginning a group”. There’s GUILayer.HitTest, but that seems to be for a different, even older GUI system (making me wonder why GUILayer is still being added to cameras by default, along with FlareLayer which also seems ancient)…

1 Like