UnityRef is currently in early development. Some features may be incomplete and/or not functioning.

UNITYREF

Your Pit Stop For Solving ANYTHING in Unity

editor

[Editor] Fix Serialized List Data Resetting in Play Mode

Solution

serializationeditor scriptingeditormemory managementdata structures

Unity 2021.1.x - Unity 6.3.x

Published 16 days ago

Issue

 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.

Explanation

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:

  1. Call serializedObject.Update() to synchronize the SerializedObject with the current state of the target.
  2. Access the specific serialized list field as a SerializedProperty using serializedObject.FindProperty("fieldName").
  3. Perform all modifications, such as clearing elements or adding new ones, directly on this SerializedProperty using methods like InsertArrayElementAtIndex().
  4. Invoke serializedObject.ApplyModifiedProperties() to write the modified values back to the actual serialized object.

Additional Tips:

  • Using SerializedProperty automatically handles EditorUtility.SetDirty and allows the Undo system to track changes without manual RecordObject calls.
  • For nested classes, ensure you use FindPropertyRelative when 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.