Unity:ScriptableObject 的自定义检查器不起作用

Unity: Custom Inspector for ScriptableObject not working

我为我的一些 ScriptableObject 创建了一个自定义检查器。检查员似乎工作得很好。如果检查器中的值发生更改,则该值会在游戏中使用。但是只要我重新启动 Unity,该值就会恢复到原来的值,因此更改不会应用于该文件。我已经通过查看文件进行了检查。这是我的自定义检查器:

[CustomEditor(typeof(ScriptableObjects.OBJ))]
public class OBJEditor: UnityEditor.Editor {
    public override void OnInspectorGUI() {
        _ = DrawDefaultInspector();

        ScriptableObjects.OBJ obj = (ScriptableObjects.OBJ) target;
        obj.Offset = EditorGUILayout.Vector2Field("Offset", obj.Offset);

        ...

        EditorUtility.SetDirty(obj);
    }
}

我添加了 EditorUtility.SetDirty(bc); 行,因为我读到该行应该将更改应用于文件。 ... 代表其他一些与点上方的两条线几乎相同的线。

如何保存对 ScriptableObject 文件的更改。

在检查器的 OnEnable 方法上缓存您的转换 'target' 被认为是最佳实践。 你也有一个错字,你设置了一个名为 'bc' 的对象变量,而你的目标变量是 'obj',你还在每次绘制调用时都将它设置为脏,这将一直弄脏你的项目,最好在实际发生变化时弄脏它。

[CustomEditor(typeof(ScriptableObjects.OBJ))]
public class OBJEditor: UnityEditor.Editor 
{
    ScriptableObjects.OBJ obj = null;
    protected void OnEnable()
    {
        obj = (ScriptableObjects.OBJ)target;
    }
    public override void OnInspectorGUI() 
    {
        serializedObject.Update();

        _ = DrawDefaultInspector();

        EditorGUI.BeginChangeCheck();
        obj.Offset = EditorGUILayout.Vector2Field("Offset", obj.Offset);

        ...
        bool somethingChanged = EditorGUI.EndChangeCheck();
        if(somethingChanged)
        {
            EditorUtility.SetDirty(obj);
        }
        serializedObject.ApplyModifiedProperties();
    }
}

您需要将正确的对象传递给 EditorUtility.SetDirty(); 以标记为脏。 目前您传递的是 bc,但您需要传递 obj,因为您在代码中就是这样命名的。 这会将您的 ScriptableObject 标记为脏,一旦您 select File > Save Project,它将被保存。

所以把EditorUtility.SetDirty(bc);改成EditorUtility.SetDirty(obj);

根本不要通过 target 直接更改值!

手动设置 dirty 和 Undo/Redo 是复杂且不必要的!

总是使用内置 serializedObject and go through SerializedProperty

[CustomEditor(typeof(ScriptableObjects.OBJ))]
public class OBJEditor: UnityEditor.Editor 
{
    private SerializedProperty offset;

    private void OnEnable()
    {
        // Link the properties
        offset = serializedObject.FindProperty("Offset");
    }

    public override void OnInspectorGUI() 
    {
        DrawDefaultInspector();

        // Load the real class values into the serialized copy
        serializedObject.Update();

        // Automatically uses the according PropertyDrawer for the type
        EditorGUILayout.PropertyField(offset);

        ...

        // Write back changed values and evtl mark as dirty and handle undo/redo
        serializedObject.ApplyModifiedProperties();
    }
}

我遇到了同样的问题,需要我添加关键字

[CanEditMultipleObjects]

到 class 定义的顶部。