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

Draggable Hoverable Button

Discussion in 'Immediate Mode GUI (IMGUI)' started by shaun, Jul 4, 2008.

  1. shaun

    shaun

    Joined:
    Mar 23, 2007
    Posts:
    728
    There's been requests for getting the mouseover state of buttons, so here's the 'hoverbutton' control. It returns a richer array of values using the EventType enum. It basically uses revamped source from the generic GUI.Button control and should be useful to see how the GUI works internally. It also shows how to do simple dragging so you can build your own drag n drop system. Be careful with overlapping two of these controls, they aren't z-index aware.

    Code (csharp):
    1. using UnityEngine;
    2. public class HoverButtonScript : MonoBehaviour
    3. {
    4.     static int HoverButtonHash = "HoverButton".GetHashCode();
    5.     private Rect HoverButtonRect = new Rect(100, 100, 100, 100);
    6.     void OnGUI()
    7.     {
    8.         switch (HoverButton(HoverButtonRect, new GUIContent("HoverButton"), "button"))
    9.         {
    10.             case EventType.mouseDown:
    11.                 Debug.Log("MouseDown");
    12.                 break;
    13.             case EventType.mouseUp:
    14.                 Debug.Log("MouseUp");
    15.                 break;
    16.             case EventType.mouseDrag:
    17.                 HoverButtonRect.x = Input.mousePosition.x - (HoverButtonRect.width / 2);
    18.                 HoverButtonRect.y = (Screen.height - Input.mousePosition.y) - (HoverButtonRect.height / 2);
    19.                 break;
    20.             case EventType.mouseMove:
    21.                 GUI.Button(new Rect(HoverButtonRect.x + 100, HoverButtonRect.y, 50, 50), "Mouse\nis Over");
    22.                 break;
    23.         }
    24.     }
    25.     public static EventType HoverButton(Rect position, GUIContent content, GUIStyle style)
    26.     {
    27.         int controlID = GUIUtility.GetControlID(HoverButtonHash, FocusType.Native);
    28.         switch (Event.current.GetTypeForControl(controlID))
    29.         {
    30.             case EventType.mouseDown:
    31.                 if (position.Contains(Event.current.mousePosition))
    32.                 {
    33.                     GUIUtility.hotControl = controlID;
    34.                     Event.current.Use();
    35.                     return EventType.mouseDown;
    36.                 }
    37.                 break;
    38.             case EventType.mouseUp:
    39.                 if (GUIUtility.hotControl != controlID)
    40.                     return EventType.ignore;
    41.                 GUIUtility.hotControl = 0;
    42.                 Event.current.Use();
    43.                 if (position.Contains(Event.current.mousePosition))
    44.                     return EventType.mouseUp;
    45.                 else
    46.                     return EventType.ignore;
    47.             case EventType.mouseDrag:
    48.                 if (GUIUtility.hotControl == controlID)
    49.                 {
    50.                     Event.current.Use();
    51.                     return EventType.mouseDrag;
    52.                 }
    53.                 else
    54.                     return EventType.ignore;
    55.             case EventType.repaint:
    56.                 style.Draw(position, content, controlID);
    57.                 if (position.Contains(Event.current.mousePosition))
    58.                     return EventType.mouseMove;
    59.                 else
    60.                     return EventType.repaint;
    61.         }
    62.         if (position.Contains(Event.current.mousePosition))
    63.             return EventType.mouseMove;
    64.         else
    65.             return EventType.ignore;
    66.     }
    67. }
     
  2. Jonathan Czeck

    Jonathan Czeck

    Joined:
    Mar 17, 2005
    Posts:
    1,713
    Cool! Thanks for this.

    -Jon
     
  3. Marc

    Marc

    Joined:
    Oct 4, 2007
    Posts:
    499
    This is nice and usefull thanks!
     
  4. sjovoll

    sjovoll

    Joined:
    Jun 4, 2008
    Posts:
    7
    That looks very interesting! You don't have a javascript-version available, by any chance? :)
     
  5. Jessy

    Jessy

    Joined:
    Jun 7, 2007
    Posts:
    7,325
    Code (csharp):
    1. var HoverButtonRect : Rect = new Rect(100, 100, 100, 100);
    2. private var HoverButtonHash : int = "HoverButton".GetHashCode();
    3.  
    4. function OnGUI()
    5. {
    6.     switch (HoverButton(HoverButtonRect, new GUIContent("HoverButton"), "button"))
    7.     {
    8.         case EventType.mouseDown:
    9.             Debug.Log("MouseDown");
    10.             break;
    11.         case EventType.mouseUp:
    12.             Debug.Log("MouseUp");
    13.             break;
    14.         case EventType.mouseDrag:
    15.             HoverButtonRect.x = Input.mousePosition.x - (HoverButtonRect.width * .5);
    16.             HoverButtonRect.y = (Screen.height - Input.mousePosition.y) - (HoverButtonRect.height * .5);
    17.             break;
    18.         case EventType.mouseMove:
    19.             GUI.Button(new Rect(HoverButtonRect.x + 100, HoverButtonRect.y, 50, 50), "Mouse\nis Over");
    20.             break;
    21.     }
    22. }
    23.  
    24. function HoverButton(position : Rect, content : GUIContent, style : GUIStyle) : EventType {
    25.     var controlID : int = GUIUtility.GetControlID(HoverButtonHash, FocusType.Native);
    26.     switch (Event.current.GetTypeForControl(controlID)){
    27.         case EventType.mouseDown:
    28.             if (position.Contains(Event.current.mousePosition)){
    29.                 GUIUtility.hotControl = controlID;
    30.                 Event.current.Use();
    31.                 return EventType.mouseDown;
    32.             }
    33.             break;
    34.         case EventType.mouseUp:
    35.             if (GUIUtility.hotControl != controlID){
    36.                 return EventType.ignore;
    37.             }
    38.             GUIUtility.hotControl = 0;
    39.             Event.current.Use();
    40.             if (position.Contains(Event.current.mousePosition)){
    41.                 return EventType.mouseUp;
    42.             }
    43.             else {
    44.                 return EventType.ignore;
    45.             }
    46.         case EventType.mouseDrag:
    47.             if (GUIUtility.hotControl == controlID){
    48.                 Event.current.Use();
    49.                 return EventType.mouseDrag;
    50.             }
    51.             else {
    52.                 return EventType.ignore;
    53.             }
    54.         case EventType.repaint:
    55.             style.Draw(position, content, controlID);
    56.             if (position.Contains(Event.current.mousePosition))
    57.                 return EventType.mouseMove;
    58.             else
    59.                 return EventType.repaint;
    60.     }
    61.     if (position.Contains(Event.current.mousePosition))
    62.         return EventType.mouseMove;
    63.     else
    64.         return EventType.ignore;
    65. }
     
  6. magwo

    magwo

    Joined:
    May 20, 2009
    Posts:
    402
    Very useful script, thank you.

    I wonder why Unity didn't make it this way to begin with, or at least provide an out parameter to get this kind of stuff:

    Code (csharp):
    1. EventType type;
    2. if(GUI.Button(..., out type)) ...
     
  7. ebubar

    ebubar

    Joined:
    Apr 16, 2010
    Posts:
    1
    Is there a simple way to use this hoverbutton script and snap the object into a grid. For my purposes at the moment, i'm trying to determine if I could reasonably teach myself this program well enough to create a pseudo-3d game ala SIMCITY. I have to develop an education component for a research proposal and would like to leverage UNITY to make a FARMVILLE-type webgame/facebook app that would have broad appeal and be educational at the same time.
     
  8. andeeeee

    andeeeee

    Joined:
    Jul 19, 2005
    Posts:
    8,768
    Hi, welcome to the forum!

    You can probably use this technique or something similar to drag items that can snap to a grid. To create a pseudo-3D game in Unity, you would most likely set up the game world in normal 3D space and then use an orthogonal camera for the isometric effect. Then, snapping to a grid is largely a matter of defining the size of the grid square and moving dragged/dropped objects to the nearest multiple of the square size on each coordinate.

    If you can give a bit more detail about your project, it might be easier to suggest some more concrete implementation ideas. However, it's probably best if you start a new thread, since it is really a separate topic from the draggable button.
     
  9. unitymatrix

    unitymatrix

    Joined:
    Dec 29, 2009
    Posts:
    120
    I have the same question too~
    is there any way that
    Code (csharp):
    1. ***.HoverButton(position,Content,style)
    to use this "Button" in another script?
     
  10. andeeeee

    andeeeee

    Joined:
    Jul 19, 2005
    Posts:
    8,768
    If you put the HoverButton function in a script and declare it static:-
    Code (csharp):
    1. static function HoverButton(...) {
    ...then you can use it from any other script. For example, if the file where the function is declared is called Hover.js, you can call it using:-
    Code (csharp):
    1. Hover.HoverButton(...);
     
  11. unitymatrix

    unitymatrix

    Joined:
    Dec 29, 2009
    Posts:
    120
    C# is different~
    and this not apply for C#
    how to do it in C#?
     
  12. Dreamora

    Dreamora

    Joined:
    Apr 5, 2008
    Posts:
    26,601
    its just public static void instead of static function
     
  13. Ailos

    Ailos

    Joined:
    Sep 14, 2011
    Posts:
    13
    Hello

    I'd like to know if it is possible to detect when you hold down the mouse button.

    Thanks