[Editor] Fix Serialized List Data Resetting in Play Mode
Solution
Unity 2021.1.x - Unity 6.3.x
Published 16 days ago
A persistence issue occurs when a SerializedProperty populated via a custom editor button in Edit Mode resets its values to default upon entering Play Mode or restarting the Unity Editor. This happens despite marking the class as [System.Serializable], attempting Undo.RecordObject, and calling EditorUtility.SetDirty because direct object manipulation is not flagged for the underlying YAML serialization.
When modifying serialized data through custom editor scripts, it is crucial to interact with the data through SerializedObject and SerializedProperty rather than directly casting the target object. Directly casting the target and modifying its fields only affects an in-memory copy of your script, which does not persist changes to the scene or asset file, leading to data loss upon entering Play Mode. This approach also bypasses the built-in undo/redo system.
To correctly persist changes and enable undo functionality, the custom editor must utilize the serializedObject property of the Editor class:
- Call
serializedObject.Update()to synchronize theSerializedObjectwith the current state of the target. - Access the specific serialized list field as a SerializedProperty using
serializedObject.FindProperty("fieldName"). - Perform all modifications, such as clearing elements or adding new ones, directly on this SerializedProperty using methods like
InsertArrayElementAtIndex(). - Invoke
serializedObject.ApplyModifiedProperties()to write the modified values back to the actual serialized object.
Additional Tips:
- Using SerializedProperty automatically handles
EditorUtility.SetDirtyand allows theUndosystem to track changes without manualRecordObjectcalls. - For nested classes, ensure you use
FindPropertyRelativewhen accessing fields inside a SerializedProperty element. - Avoid using
AssetDatabase.SaveAssets()for scene-based changes as it triggers a full project re-serialization which is expensive and unnecessary.
TL;DR
To ensure data persistence and proper undo functionality for serialized lists within custom scripts, modifications must be made via SerializedProperty instead of directly casting the target object.
Related Posts Haven't quite found a solution to your problem? We think these posts might help you.
Content inspired by a Unity discussion post.