1

I've set up a very simple Editor script in Unity 2020.2.1f1 that, upon pressing an Inspector button, should change the value of a specified parameter to a value set in the code.

public override void OnInspectorGUI()
{
    DrawDefaultInspector();

    StateObject s = (StateObject)target;
    if (s.objID == 0)
    {
        if (GUILayout.Button("Generate Object ID"))
        {
            GenerateID(s);
        }
    }
}

public void GenerateID(StateObject s)
{
    s.objID = DateTimeOffset.Now.ToUnixTimeSeconds();
}

This all works like it's supposed to. I press the button, the correct number appears in the field, and I'm happy. However, once I switch to Play mode, the value resets to the prefab default and remains that way even when I switch Play mode off.

Am I missing some ApplyChange function or something?

2 Answers 2

2

(EDIT: This works, but isn't as good as the accepted answer.)

Well, yes, I am in fact missing some sort of ApplyChange function.

I don't know how I missed it, but I was looking for this:

EditorUtility.SetDirty(target);

So, in my script, I would just edit the GenerateID function:

public void GenerateID(StateObject s)
{
    s.objID = DateTimeOffset.Now.ToUnixTimeSeconds();
    EditorUtility.SetDirty(s);
}

And I am posting it here in case anyone runs into the same issue, that way they hopefully won't have to spend as much time looking for a solution before being reminded that SetDirty is a thing.

Sign up to request clarification or add additional context in comments.

Comments

1

In my eyes better than mixing in direct accesses from Editor scripts and then manually mark things dirty rather go through SerializedProperty and let the Inspector handle it all (also the marking dirty and saving changes, handle undo/redo etc)

SerializedProperty id;

private void OnEnable()
{
    id = serializedObject.FindProperty("objID");
}

public override void OnInspectorGUI()
{
    DrawDefaultInspector();

    // Loads the actual values into the serialized properties
    // See https://docs.unity3d.com/ScriptReference/SerializedObject.Update.html
    serializedObject.Update();

    if (id.intValue == 0)
    {
        if (GUILayout.Button("Generate Object ID"))
        {
            id.intValue = DateTimeOffset.Now.ToUnixTimeSeconds();
        }
    }

    // Writes back modified properties into the actual class
    // Handles all marking dirty, undo/redo, etc
    // See https://docs.unity3d.com/ScriptReference/SerializedObject.ApplyModifiedProperties.html
    serializedObject.ApplyModifiedProperties();

}

1 Comment

Thanks! I had found something similar to this, but not as complete. I had tried it but it didn't work. Your example actually does work! Thanks again!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.