Color change of GUI button in custom Unity Editor is significantly delayed

5.3k views Asked by At

When I try to make a GUI button in the Unity Editor change colors on hover, the color change is successful but horribly delayed. Here is a gif of the button's activity when the mouse hovers over it:

gif of the button changing color slowly when hovered

As you can see, the color change is considerably delayed. I need to find a way to speed this up to where the button changes color as soon as the mouse hits it

Here's the minimum code needed to reproduce the example. First, the empty class used to create the editor:

using UnityEngine;
public class Test : MonoBehaviour
{
   
}

Then, the custom editor used to create the button:

using UnityEngine;
using UnityEditor;

[CustomEditor(typeof(Test))]
public class TestEditor : Editor
{
    public override void OnInspectorGUI()
    {
        base.OnInspectorGUI();

        GUIStyle style = new GUIStyle()
        {
            alignment = TextAnchor.MiddleCenter,
            fontStyle = FontStyle.Bold,

            normal = new GUIStyleState()
            {
                background = Texture2D.whiteTexture
            },
            hover = new GUIStyleState()
            {
                background = Texture2D.grayTexture
            },
            active = new GUIStyleState()
            {
                background = Texture2D.blackTexture
            }
        };

        GUILayout.Button("Hello!", style);
    }
}

If you attach this emtpy "Test" class to a GameObject in the Unity scene, you should get the editor pictured at the top of the post.

Is there some workaround to make this color change faster and more responsive? Any advice is greatly appreciated!

1

There are 1 answers

0
Milan Egon Votrubec On

You could force a repaint of the Inspector window, by calling Repaint(). The quickest way to do that would be to use a Task with a, say, 100ms delay, like this:

[CustomEditor ( typeof ( Test ) )]
public class TestEditor : Editor
{
    GUIStyle style;
    private bool repaint;

    private void Awake ( )
    {
        style = new GUIStyle ( )
        {
            alignment = TextAnchor.MiddleCenter,
            fontStyle = FontStyle.Bold,
            normal = new GUIStyleState ( ) { background = Texture2D.whiteTexture },
            hover = new GUIStyleState ( ) { background = Texture2D.grayTexture },
            active = new GUIStyleState ( ) { background = Texture2D.blackTexture }
        };

        repaint = true;
        Repainter ( );
    }

    private void OnDisable ( )
    {
        Debug.Log ( "repaint = false" );
        repaint = false;
    }

    async void Repainter ( )
    {
        while ( repaint )
        {
            this.Repaint ( );
            await Task.Delay ( 100 );
        }
    }

    public override void OnInspectorGUI ( )
    {
        base.OnInspectorGUI ( );
        GUILayout.Button ( "Hello!", style );
    }
}

I'd also like to point out that I wouldn't necessarily recommend doing this, but it shouldn't hurt. And I turn it on and off only when the inspector window is visible. If you can increase the delay eve further, until you get to a acceptable response behaviour, I feel it would be better for everyone involved.

An EditorWindow is updated 10 times a second as well. So it would seem that Unity themselves are fairly happy with that number of window refreshes a second. Unity Docs : EditorWindow.OnInspectorUpdate

That should give you a snappier inspector button.