- Home /
Saving changes to mixed CustomInspector
I'm often in the situation where I need some GUI behaviour that does not have a serializedProperty override. For example, I want to use BeginToggleGroup
which is a classic control, but the controls inside the toggle group can use a Property Field. In this case I'm mixing the Property Field method with the classic method of directly assigning to the target object.
Examples to show what I mean by "classic" vs "Property Field".
Classic:
target.someVariable = EditorGUILayout.Toggle("someVariable", target.someVariable)
Property Field:
EditorGUILayout.PropertyField(serializedObject.FindProperty("someVariable"));
I can't figure out how to save the data using the PropertyField
in this case. Whatever I do, changes to someValue
in the example below get reverted after deselecting the field. Changes to anotherValue
and enabled
are preserved fine; because they use the "classic" method of newValue = EditorGUILayout.SomeField( "label", oldValue )
.
But the way I understand it, property fields are preferable because they support undo, multi-object editing, and show local prefab changes.
public class ComplexComponent : MonoBehaviour { //not really, haha
public bool enabled;
public float someValue;
public bool anotherValue;
}
The editor looks like this:
public override void OnInspectorGUI () {
ComplexComponent comp = (ComplexComponent)target;
comp.enabled = EditorGUILayout.BeginToggleGroup("Enabled", comp.enabled);
EditorGUILayout.PropertyField(serializedObject.FindProperty("someValue"));
comp.anotherValue = EditorGUILayout.ToggleLeft("Another Value", comp.anotherValue);
EditorGUILayout.EndToggleGroup();
}
Additionally, changes to the "classic" fields are not even saved when saving/quitting the scene!
Answer by brunocoimbra · Jan 07, 2016 at 06:30 PM
Try adding those 2 lines:
public override void OnInspectorGUI () {
// It must be on top:
serializedObject.Update();
ComplexComponent comp = (ComplexComponent)target;
comp.enabled = EditorGUILayout.BeginToggleGroup("Enabled", comp.enabled);
EditorGUILayout.PropertyField(serializedObject.FindProperty("someValue"));
comp.anotherValue = EditorGUILayout.ToggleLeft("Another Value", comp.anotherValue);
EditorGUILayout.EndToggleGroup();
// It must be at bottom:
serializedObject.ApplyModifiedProperties();
}
Not sure, but maybe it will solve your problems.
This helps! Changes to the Property Field are now preserved! I tried these but I did not know about the Update()
call at the start.
However, direct changes to the object still don't result in the scene being marked as "edited".
Try using the serialized object, not the target instance, like that:
using System.Collections;
using UnityEditor;
using UnityEngine;
[CustomEditor(typeof(ComplexComponent))]
[CanEdit$$anonymous$$ultipleObjects]
public class TestEditor : Editor
{
SerializedProperty enabled;
SerializedProperty someValue;
void OnEnable()
{
enabled = serializedObject.FindProperty("enabled");
someValue = serializedObject.FindProperty("someValue");
}
public override void OnInspectorGUI()
{
serializedObject.Update();
enabled.boolValue = EditorGUILayout.BeginToggleGroup("Enabled", enabled.boolValue);
EditorGUILayout.PropertyField(serializedObject.FindProperty("someValue"));
// I've removed the "anotherValue", ComplexComponent class doens't have that variable...
// Why were you trying to get it?
EditorGUILayout.EndToggleGroup();
serializedObject.Apply$$anonymous$$odifiedProperties();
}
}
This is a really good suggestion, I never thought of doing that! Will modifying the boolValue
on the serializedObject also set the correct Undo state and deal with multi-object editing?
I never saw the reference for "Editor" before, but it would have been really helpful, they even compare using PropertyField and using "old" (what I called "classic") method! http://docs.unity3d.com/ScriptReference/Editor.html