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

时间:2019-09-15 07:53:24

标签: c# unity3d save scriptable-object

我为我的一些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文件。

4 个答案:

答案 0 :(得分:1)

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

手动设置脏和撤消/重做是复杂且不必要的!

始终使用内置的serializedObject并通过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();
    }
}

答案 1 :(得分:0)

在检查器的OnEnable方法上缓存投射的“目标”被认为是最佳实践。 您还有一个错字,您正在设置目标变量为'obj'的对象变量'bc'的肮脏状态,并且还在每次绘制调用时对其进行污染的设置,这将使您的项目一直肮脏,最好是对其进行污染实际发生什么变化。

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

答案 2 :(得分:0)

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

因此将EditorUtility.SetDirty(bc);更改为EditorUtility.SetDirty(obj);

答案 3 :(得分:0)

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

[CanEditMultipleObjects]

到类定义的顶部。