5
\$\begingroup\$

I have a custom editor script which I have used to neatly arrange a huge group of variables into tabs. Some of these variables change in the script and it's very useful to see what they are without printing them to the console. Before I wrote my custom inspector the values would change at runtime as expected. However, after writing my custom inspector the values only update when I first click the object in the hierarchy.

How would I go about making my editor script update whenever the values change?

This is my stripped down code:

using UnityEngine;
using UnityEditor;

[CanEditMultipleObjects]
[CustomEditor(typeof(Car))]
public class CarEditor : Editor
{
    private SomeScript myTarget;
    private SerializedObject soTarget;

    private const string tab1 = "tab1";
    private const string tab2 = "tab2";
    private const string tab3 = "tab3";

    private SerializedProperty var1;
    private SerializedProperty var2;
    private SerializedProperty var3;

    private void OnEnable()
    {
        myTarget= (SomeScript)target;
        soTarget = new SerializedObject(target);

        var1 = soTarget.FindProperty("var1");
        var2 = soTarget.FindProperty("var2");
        var2 = soTarget.FindProperty("var2");
    }

    public override void OnInspectorGUI()
    {
        //DrawDefaultInspector();
        EditorGUI.BeginChangeCheck();

        myTarget.toolbarTab = GUILayout.Toolbar(myTarget.toolbarTab, new string[] { tab1, tab2, tab3 });

        switch (myTarget.toolbarTab)
        {
            case 0:
                myTarget.currentTab = tab1;
                break;
            case 1:
                myTarget.currentTab = tab2;
                break;
            case 2:
                myTarget.currentTab = tab3;
                break;
        }

        if (EditorGUI.EndChangeCheck())
        {
            soTarget.ApplyModifiedProperties();
            GUI.FocusControl(null);
        }

        switch (myTarget.currentTab)
        {
            case tab1:
                EditorGUILayout.PropertyField(var1, true);
                break;
            case tab2:
                EditorGUILayout.PropertyField(var2, true);
                break;
            case tab3:
                EditorGUILayout.PropertyField(var3, true);
                break;
        }
    }
}
\$\endgroup\$

3 Answers 3

3
\$\begingroup\$

I just ran into this problem for the first myself... surprised there's no answer to be found anywhere.

After poking at it for a bit, I found a solution myself. Turns out, an inspector doesn't repaint unless you interact with it, even if the values it's displaying update runtime. You can force it to refresh once per frame by placing:

if (EditorApplication.isPlaying)
  Repaint();

At the bottom of your OnInspectorGUI override. I suspect this is what the default inspectors are doing behind the scenes.

\$\endgroup\$
3
\$\begingroup\$

Override RequiresConstantRepaint(): https://docs.unity3d.com/ScriptReference/Editor.RequiresConstantRepaint.html

\$\endgroup\$
0
\$\begingroup\$

Stacked with exactly the same problem.

What this code does is change the label above objects(in my case players) head. Inside OnInspectorGUI:

EditorGUI.BeginChangeCheck();

int currentScore = EditorGUILayout.IntField(...)

if (EditorGUI.EndChangeCheck())
{
    (sp.objectReferenceValue as Object).ChangeLabelAboveObject(currentScore);
    EditorApplication.QueuePlayerLoopUpdate();
    GUI.FocusControl(null);
}

Explanation: sp - SerializedProperty, Object - any MonoBehaviour you like.

But the main: everything goes ok when I added EditorApplication.QueuePlayerLoopUpdate.

Hope this will help someone, because I was looking for this for hours.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .