This is a bit of a tricky issue to summarize in a title, but after testing I’m fairly sure it’s a bug. I have a class, SPUndo, and it has a reference to a subclass, SPUndoSubclass.
public class SPUndoSubclass
{
public int primitive;
}
public class SPUndo : MonoBehaviour
{
[SerializeReference]
SPUndoSubclass reference;
}
I’m trying to add and remove an instance of SPUndoSubclass. Click the [+] button to create an instance, click [-] to remove it. Here’s the issue:
- When the editor UI is created and reference != null: every modification to reference triggers a notification.
- When the editor UI is created and reference == null: Assigning a new instance to reference triggers an event. However, no subsequent change (which entails = null) sends a notification. This is the issue. Here’s the example code below:
[CustomEditor(typeof(SPUndo))]
public class SPUndoInspector : Editor
{
private Button AddButton;
private Button RemoveButton;
private PropertyField PrimitiveField;
public override VisualElement CreateInspectorGUI()
{
VisualElement visualInput = new VisualElement();
AddButton = new Button(AddButton_clicked);
AddButton.text = "+";
RemoveButton = new Button(RemoveButton_clicked);
RemoveButton.text = "-";
PrimitiveField = new PropertyField();
SerializedProperty referenceProperty = serializedObject.FindProperty("reference");
ReferenceChangedCallback(referenceProperty);
BindingExtensions.TrackPropertyValue(visualInput, referenceProperty, ReferenceChangedCallback);
visualInput.Add(AddButton);
visualInput.Add(RemoveButton);
visualInput.Add(PrimitiveField);
return visualInput;
}
void ReferenceChangedCallback(SerializedProperty property)
{
UnityEngine.Debug.Log("ReferenceChangedCallback");
PrimitiveField.Unbind();
if (property.managedReferenceValue == null)
{
AddButton.SetEnabled(true);
RemoveButton.SetEnabled(false);
PrimitiveField.visible = false;
}
else
{
AddButton.SetEnabled(false);
RemoveButton.SetEnabled(true);
PrimitiveField.visible = true;
BindingExtensions.BindProperty(PrimitiveField, property.FindPropertyRelative("primitive"));
}
}
private void AddButton_clicked()
{
serializedObject.Update();
serializedObject.FindProperty("reference").managedReferenceValue = new SPUndoSubclass();
serializedObject.ApplyModifiedProperties();
}
private void RemoveButton_clicked()
{
serializedObject.Update();
serializedObject.FindProperty("reference").managedReferenceValue = null;
serializedObject.ApplyModifiedProperties();
}
}