Search Unity

Weird Button hover behaviour in GUI

Discussion in 'Editor & General Support' started by kimsungjinDC, May 17, 2021.

  1. kimsungjinDC

    kimsungjinDC

    Joined:
    Jul 16, 2020
    Posts:
    5
    Default GUI button mouse hover effect show immediately. But custom skin button does not.

    Default button receives EventType.Layout,Redraw event as soon as mouse is inside button, but custom skin button does not.

    Why is this happening?

    Code (CSharp):
    1. void OnGUI()
    2.     {
    3.         GUI.skin = mySkin;
    4.         GUILayout.BeginArea(new Rect(200, 200, 300, 600));
    5.         GUILayout.Button("Custom Skin Button");
    6.         GUI.skin = null;
    7.         GUILayout.Button("WorldIsNotGood");
    8.         GUILayout.EndArea();
    9.     }
     

    Attached Files:

  2. M4dR0b

    M4dR0b

    Joined:
    Feb 1, 2019
    Posts:
    108
    Y-Hello there,

    not very familiar with GUI skin, trying in the game of guessing I'd say that the internal button has a skin which defines by default the "On Hover" behavior, yours does not.

    Have you try to check if your custom skin has an option to define the Hover behavior?
     
  3. kimsungjinDC

    kimsungjinDC

    Joined:
    Jul 16, 2020
    Posts:
    5


    Actually there is an image on Hover, OnHover both.

    It's just a GUISkin that you can make with Mouse Right click and Create GUISkin.

    Those Button images are inside by default.
     
  4. M4dR0b

    M4dR0b

    Joined:
    Feb 1, 2019
    Posts:
    108
    That is weird, I've just tried your script with a new GUI skin and the components are working as expected.



    What version of unity are you in and what SRP (HDRP, URP, etc)?

    still guessing: Have you tried creating a new skin? a clear project with just that GUI? Is there something that might be blocking the Event System raycast?
     
  5. kimsungjinDC

    kimsungjinDC

    Joined:
    Jul 16, 2020
    Posts:
    5
    Thanks for testing. I'm testing this inside EditorWindow, Not in Monobehaviour OnGUI Script.

    Difference is EditorWindow OnGUI doesn't called everytime, but MonoBehaviour OnGUI called every frame.
     
    Last edited: May 17, 2021
  6. M4dR0b

    M4dR0b

    Joined:
    Feb 1, 2019
    Posts:
    108
    You are right, it does seem that with custom GUISkin the refresh is slower.
    I'm sorry but I have no clue why this is happening.



    [EDIT]

    it seems that adding Repaint() at the end of OnGUI() helps with the refresh, but I've got no idea if this is creating overhead



    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEditor;
    3.  
    4. public class GUIController : EditorWindow
    5. {
    6.     public GUISkin mySkin;
    7.  
    8.     // Add menu named "My Window" to the Window menu
    9.     [MenuItem("Window/My Window")]
    10.     static void Init()
    11.     {
    12.         // Get existing open window or if none, make a new one:
    13.         GUIController window = (GUIController)EditorWindow.GetWindow(typeof(GUIController));
    14.         window.Show();
    15.     }
    16.  
    17.     void OnGUI()
    18.     {
    19.         GUI.skin = mySkin;
    20.         GUILayout.BeginArea(new Rect(200, 200, 300, 600));
    21.         GUILayout.Button("Custom Skin Button");
    22.         GUI.skin = null;
    23.         GUILayout.Button("WorldIsNotGood");
    24.         GUILayout.EndArea();
    25.         Debug.Log("calling");
    26.         Repaint();
    27.     }
    28. }
     
  7. kimsungjinDC

    kimsungjinDC

    Joined:
    Jul 16, 2020
    Posts:
    5
    Thanks for testing. @M4dR0b

    Repaint wont be that overhead unless you have many many GUI to renderer. Or if we cound make
    "this.wantsMouseMove = true" then EventType.MouseDown will be fired everytime you move your mouse, then when MouseDown event occurs, we could call Repaint. That might relief some overload.

    I'll share what I have been discovered so far about this bizzare GUI behaviour.

    The custom skin button's delayed rendering is caused by event that when you stop moving your mouse cursor for second, then automatically EventType.Repaint occurs. I saw a post someone says that delayed event is for showing tooltip rendering when you hover your mouse on some control and stationary for some second.

    So, that delayed button highting is just different story, the problem is default button emits EventType.Repaint as soon as mouse cursor enters button rect, but custom style button does not.

    Button is rendered using GUIStyle.Draw function. GUI.Button function calls it internally. If you try rendering two different Style,
    Code (CSharp):
    1. void OnGUI()
    2.     {
    3.         GUI.skin.button.Draw(new Rect(10,10,100,100),"This Default Style button emits EventType.Repaint when cursor enters",false,false,false,false);
    4.         mySkin.button.Draw(new Rect(100,10,100,100),"This Custom Style button does not",false,false,false,false);
    5.     }
    Default Style Button emits EventType.Repaint, but Custom Style does not.

    I really want to know what is happening undearneath GUIStyle.Draw but code is externally implemented which its Unity engine side code so i cannot see.

    Can some Unity Dev help me with this thing?
     
    M4dR0b likes this.
  8. Cameron_SM

    Cameron_SM

    Joined:
    Jun 1, 2009
    Posts:
    915
    I'm also encountering this in 2020.3.24

    Would love to know why there's different behaviour from GUIStyle.Draw when using custom skin vs default editor skin. This feels like a bug.
     
  9. alicewithalex

    alicewithalex

    Joined:
    Jan 18, 2018
    Posts:
    21
    Yeah, still don't know how to avoid it :( Also I noticed some very helpful internal function in UnityCsReferences in GUI:
    This is calls "GrabMouseControl(int id)" and "ReleaseMouseControl(int id)" which really helpful to stop mouse events such like hovering on other elements except your current control id, in my case popup window (enum). Default enums have this feature, but I cant replicate this