Search code examples
c#unity-game-engineunity-editorunity3d-editor

Unity custom editor prefab show modified values


I have a prefab that contains a script with a custom editor. The prefab is then modified in a scene, including the script itself.

What I want is for the script's modified variables to be bolded out, like this: bold variable

But instead, the variable modified outside the prefab looks just like any other (unchanged) variables. I've tried using Undo.RecordObject and EditorUtility.SetDirty but no luck. Perhaps there's something here that I've missed, such as what I should have called or the order of the lines?

I have been searching and testing scripts for hours without luck, it would be great if anyone could inform me what I've been doing wrong.

The editor script looks like the following:

using UnityEditor;
using UnityEngine;
using UnityEditor.SceneManagement;
using UnityEngine.SceneManagement;

[CustomEditor (typeof (MyScript))]
[CanEditMultipleObjects]
public class MyScriptEditor : Editor {

    SerializedProperty usePanel, [...], equalHints;

    protected virtual void OnEnable () {
        setvars ();
    }
    void setvars () {
        usePanel = serializedObject.FindProperty ("usePanel");
        // ...and more variables...
        equalHints = serializedObject.FindProperty ("equalHints");
        MyScript s = (MyScript) target;
        Undo.RecordObject (s, "test");
    }

    public override void OnInspectorGUI () {
        if (usePanel.Equals (null)) setvars ();
        MyScript s = (MyScript) target;
        if (GUI.changed) {
            EditorUtility.SetDirty (s); // <--- this was one of my attempts
            EditorSceneManager.MarkSceneDirty (SceneManager.GetActiveScene ());
        }

        usePanel.boolValue = EditorGUILayout.Toggle ("Use Panel", usePanel.boolValue);
        // some more lines of code here
        if (equalHints.boolValue) {
            // do some stuff
        }
        this.serializedObject.ApplyModifiedProperties ();
    }
}

Solution

  • Rather directly use a PropertyField like

    [CustomEditor (typeof (MyScript))]
    [CanEditMultipleObjects]
    public class MyScriptEditor : Editor 
    {
        SerializedProperty usePanel /*, ... */, equalHints;
    
        protected virtual void OnEnable () 
        {
            setvars ();
        }
    
        void setvars () 
        {
            usePanel = serializedObject.FindProperty("usePanel");
            // ...and more variables...
            equalHints = serializedObject.FindProperty("equalHints");
        }
    
        public override void OnInspectorGUI () 
        {
            // don't forget this one
            // this gets the current values into the serialized properties
            serializedObject.Update();
    
            EditorGUILayout.PropertyField(usePanel);
    
            EditorGUILayout.PropertyField(equalHints);
    
            if (equalHints.boolValue) 
            {
                // do some stuff
            }
    
            serializedObject.ApplyModifiedProperties();
        }
    }
    

    This way the property field(s)

    • simply use the correct drawer according to your field type
    • automatically handles marking dirty (and thereby saving and undo/redo). There is no need for you handling all that dirty marking and redo tracking