Unity editor not saving object changes

I’m currently making a custom inspector script for one of my scripts that allows user input to set a inspector read only variable on the script, with background checking. The script works and sets this variable but after saving the scene, project and restarting unity the variable is now empty.

I’ve tried force saving the scene and project via script but also this does not work.

The variable script snippet:

public class Object : OWSGBehaviour
{

    [ShowOnly, SerializeField] protected string _databaseID = "null";

    // Details

    /// <summary>
    /// Item Database ID (SET ONLY FOR OBJECT DATABASE USE)
    /// </summary>
    public string DatabaseID
    {
        get
        {
            return _databaseID;
        }

        set
        {
            _databaseID = value;
        }
    }

The custom inspector code:

[CustomEditor(typeof(Object), true)]
public class EditorObjectInspectorAdd : Editor {

    private static EditorObjectInspectorAddPopup popup;
    private static Object myTarget;

    static EditorObjectInspectorAdd()
    {
        EditorObjectInspectorAddPopup.WindowClosed += ReceiveId;
    }

    public override void OnInspectorGUI()
    {
        myTarget = (Object)target;
        if (GUILayout.Button("Set Database ID"))
        {
            popup = ScriptableObject.CreateInstance<EditorObjectInspectorAddPopup>();
            popup.position = new Rect(Screen.width / 2, Screen.height / 2, 250, 75);
            popup.ShowUtility();
        }

        DrawDefaultInspector();
    }

    static void ReceiveId(string id)
    {
        if(myTarget.DatabaseID == "null")
        {
            myTarget.DatabaseID = id;
        }
        else
        {
            Debug.Log("Object Updated from " + myTarget.DatabaseID + " to: " + id);
            ObjectDatabaseEditor.UpdateID(myTarget.DatabaseID, id);
            myTarget.DatabaseID = id;
        }

        // Trying to force save changes - no dice
        EditorApplication.SaveAssets();
        EditorSceneManager.SaveCurrentModifiedScenesIfUserWantsTo();

    }
}

public class EditorObjectInspectorAddPopup : EditorWindow
{
    public delegate void OnWindowClose(string id);
    public static event OnWindowClose WindowClosed;

    bool allowed = false;
    string input = "";
    string lastInput = "";

    void OnGUI()
    {
        EditorGUILayout.LabelField("Input ID (10 Char max):");
        input = EditorGUILayout.TextField(input, EditorStyles.textField);
        input = input.Replace(" ", "");

        if (input != lastInput)
        {
            lastInput = input;
            allowed = ObjectDatabaseEditor.IsIDavaliable(input);
        }

        if (allowed)
        {
            if (GUILayout.Button("Agree!"))
            {
                if (WindowClosed != null)
                    WindowClosed(input);
                this.Close();
            }
        } else
        {
            EditorGUILayout.LabelField("ID is currently taken or not avaliable");
        }
    }
}

You’ll need to use EditorUtility.SetDirty().

EDIT: In Unity 5.3 onward, you’ll want to use Undo.RecordObject(). I’d recommend looking these up in the scripting reference.

It looks like you also need to mark the scene as dirty with

UnityEditor.SceneManagement.EditorSceneManager.MarkAllScenesDirty();

Or if you know which scene you are editing, you can use

UnityEditor.SceneManagement.EditorSceneManager.MarkSceneDirty(Scene);

I was stuck in a similar place and was messing with serializedObject.ApplyModifiedProperties() and SetDirty for a really long time before I figured out what was happening. I’m using a mix of PropertyFields and directly setting the public properties on my target. Like this:

fontProperty = serializedObject.FindProperty("FontSize");

solutionObj = target as SolutionObject;
EditorGUILayout.PropertyField(fontProperty );

solutionObj.TextLabel = EditorGUILayout.TextField(TextLabel , EditorStyles.textField);

serializedObject.ApplyModifiedProperties();

It turns out the ApplyModifiedProperties() call was overwriting the TextLabel, and trashing the value the TextField had set. I got around this by applying the TextLabel changes AFTER the ApplyModifiedProperties() call. I think this is because the serializedObject copy of the data just gets dumped on top of the actual objects data when they are applied.

In addition to UnityEditor.Undo.RecordObject(this, "Description"); you may need to run UnityEditor.PrefabUtility.RecordPrefabInstancePropertyModifications(this);