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 定义的顶部。
我为我的一些 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 定义的顶部。