Unity 在播放时重置使用编辑器脚本设置的参数值

Unity resets parameter value set with Editor script on play

我在 Unity 2020.2.1f1 中设置了一个非常简单的编辑器脚本,按下 Inspector 按钮后,应该将指定参数的值更改为代码中设置的值。

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();
}

一切正常。我按下按钮,正确的数字出现在字段中,我很高兴。但是,一旦我切换到播放模式,该值就会重置为预制默认值,即使我关闭播放模式也会保持这种状态。

我是不是遗漏了一些 ApplyChange 函数之类的?

(编辑:这有效,但不如公认的答案好。)

嗯,是的,我实际上缺少某种 ApplyChange 函数。

我不知道我是怎么错过的,但我一直在找这个:

EditorUtility.SetDirty(target);

因此,在我的脚本中,我将只编辑 GenerateID 函数:

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

我将它发布在这里以防万一有人遇到同样的问题,这样他们就不会在被提醒 SetDirty 是一个问题之前花那么多时间寻找解决方案。

在我看来,这比混合从编辑器脚本直接访问然后手动标记脏东西更好,而不是通过 SerializedProperty 并让 Inspector 处理所有事情(还有标记脏和保存更改,处理 undo/redo等)

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();

}