Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

GUI.Button() hover detection?

Discussion in 'Immediate Mode GUI (IMGUI)' started by RockHound, Oct 19, 2007.

  1. RockHound

    RockHound

    Joined:
    Apr 14, 2006
    Posts:
    132
    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.
     
  2. NicholasFrancis

    NicholasFrancis

    Joined:
    Apr 8, 2005
    Posts:
    1,587
    You need to check the mouse position against the button's rect.
     
  3. Deleted User

    Deleted User

    Guest

    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?
     
  4. NicholasFrancis

    NicholasFrancis

    Joined:
    Apr 8, 2005
    Posts:
    1,587
    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.
     
  5. shaun

    shaun

    Joined:
    Mar 23, 2007
    Posts:
    728
    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
     
  6. Joe ByDesign

    Joe ByDesign

    Joined:
    Oct 13, 2005
    Posts:
    841
    Thinking that since there are already a huge number of parameters, what is a few more for this important feature?

    Great to hear. :) Any version ETA?
     
  7. shaun

    shaun

    Joined:
    Mar 23, 2007
    Posts:
    728
    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
     
  8. NicholasFrancis

    NicholasFrancis

    Joined:
    Apr 8, 2005
    Posts:
    1,587
    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"
     
  9. Brian-Kehrer

    Brian-Kehrer

    Joined:
    Nov 7, 2006
    Posts:
    411
    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.
     
  10. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,773
    Something similar to GUI.changed would be great for detecting hovering. For example:

    Code (csharp):
    1.  
    2. GUI.hover=false;
    3. if (GUILayout.Button("Foo")) { Foo(); }
    4. if (GUI.hover) infoString="foobar";
    5. GUI.hover=false;
    6. if (GUILayout.Button("Bar")) { Bar(); }
    7. if (GUI.hover) infoString = "barfoo";
    8.  
    9. GUILayout.Label(infoString);
    10.  
    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....
     
  11. cecarlsen

    cecarlsen

    Joined:
    Jun 30, 2006
    Posts:
    858
    I just wanted to let the Unity developers know that I too miss the feature. It is quite essential for creating custom GUI interfaces.
     
  12. Bjerre

    Bjerre

    Joined:
    Nov 8, 2006
    Posts:
    108
    I made a simple hovering detection for our last game. It's not optimal but it works. I have included a simple example below

    Code (csharp):
    1.  
    2. var hover : String;
    3.  
    4. function OnGUI(){
    5.     GUI.Button (Rect (10,10,100,20), GUIContent ("Button 1", "Button 1"));
    6.     GUI.Button (Rect (110,10,100,20), GUIContent ("Button 2", "Button 2"));
    7.     hover = GUI.tooltip;
    8. }
    9.  
    10.  
    11. function Update () {
    12.     if(hover=="Button 1")
    13.     Debug.Log("Hovering Button 1");
    14.    
    15.     if(hover=="Button 2")
    16.     Debug.Log("Hovering Button 2");
    17. }
    18.  
    19.  
     
  13. cecarlsen

    cecarlsen

    Joined:
    Jun 30, 2006
    Posts:
    858
    Nice going Claus! =)
     
  14. Joe ByDesign

    Joe ByDesign

    Joined:
    Oct 13, 2005
    Posts:
    841
    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?
     
  15. Marc

    Marc

    Joined:
    Oct 4, 2007
    Posts:
    499
    Maybe checking like this will help

    Code (csharp):
    1.  
    2. if(Event.current.type == EventType.repaint) {
    3.  
    4.   Code that is only execute once on the gui function passes.
    5.  
    6. }
    7.  
     
  16. Joe ByDesign

    Joe ByDesign

    Joined:
    Oct 13, 2005
    Posts:
    841
    Thank you Marc, that is very helpful.
     
  17. Der Dude

    Der Dude

    Joined:
    Aug 7, 2006
    Posts:
    213
    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.
     
  18. BitVenom

    BitVenom

    Joined:
    Jan 30, 2008
    Posts:
    19
    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
     
    Haxel0rd likes this.
  19. WinterboltGames

    WinterboltGames

    Joined:
    Jul 27, 2016
    Posts:
    259
    Redacted
     
    Last edited: Jun 18, 2021
  20. NoiseFloorDev

    NoiseFloorDev

    Joined:
    May 13, 2017
    Posts:
    104
    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)...
     
    Gobey likes this.
  21. BoteRock

    BoteRock

    Joined:
    Jan 10, 2013
    Posts:
    9
    Given that this is what appeared as the first search result, I will post my solution here:
    I just wrapped some boilerplate that checks that the GUI.tooltip is the same as the given element

    Code (CSharp):
    1.  
    2. public static class MyGUI {
    3.  
    4.     static GUIContent content = new GUIContent();
    5.     public static bool hovered;
    6.    
    7.     public static bool Button(string label) {
    8.         string prevTooltip = GUI.tooltip;
    9.  
    10.         content.image = null;
    11.         content.tooltip = label;
    12.         content.text = label;
    13.         bool result = GUILayout.Button(content);
    14.         hovered = GUI.tooltip == label;
    15.  
    16.         GUI.tooltip = prevTooltip;
    17.         return result;
    18.     }
    19. }
    20.  
    Usage:

    Code (CSharp):
    1.  
    2. if (MyGUI.Button("test")) { /* do anything */ }
    3. if (MyGUI.hovered) { print("test button was hovered"); }
    4.  
     
  22. TheRealProFoxyfy

    TheRealProFoxyfy

    Joined:
    May 15, 2021
    Posts:
    1
    Add an EvenTrigger click "add event type" and select "PointerEnter" than you can do that without scripts.
     
  23. Cameron_SM

    Cameron_SM

    Joined:
    Jun 1, 2009
    Posts:
    915
    Bit of a necro but this thread is still #1 on google rankings for how to detect mouse hover in imgui. Piggybacking off the tooltip is code smell and means you have tooltips you might not want. The best solution is actually GUILayoutUtility.GetLastRect - it even has mouse hovering example in the documentation for how to use it:

    https://docs.unity3d.com/ScriptReference/GUILayoutUtility.GetLastRect.html

    Maybe this reply will bump the google ranking of that documentation page for this question and the next person will find it quicker.
     
    Javawag and Skrip037 like this.
  24. RSC_Games

    RSC_Games

    Joined:
    Apr 24, 2020
    Posts:
    3