Undo.RecordObject doesn't record array
Undo.RecordObject doesn't writes array, so when I press ctrl+z, variable count changes, but array not. Is it okay?
It is simplified example, not real code. Component with variable and array of objects:
public class DataHolder : MonoBehaviour {
[SerializeField] public Data[] array = new Data[0];
[SerializeField] private int count;
public void Reset() {
array = new Data[0];
count = 0;
}
public void AddData() {
Array.Resize(ref array, array.Length + 1);
array[array.Length - 1] = new Data();
count++;
}
}
In ideal world, count always equals array.Length. But undo operation violates this invariant :( I tried to record whole game object instead of dataHolder, but it doesn't work too.
[CustomEditor(typeof(DataHolder))]
public class HolderInspector : Editor {
public override void OnInspectorGUI() {
DrawDefaultInspector();
var dataHolder = target as DataHolder;
if (GUILayout.Button("add Data")) {
Undo.RecordObject(dataHolder, "add data");
EditorUtility.SetDirty(dataHolder);
//Undo.RecordObject(dataHolder.gameObject, "add data");
//EditorUtility.SetDirty(dataHolder.gameObject);
dataHolder.AddData();
}
GUILayout.Label("array size = " + dataHolder.array.Length);
}
}
and simple class (really it has a lot of data)
public class Data {
[SerializeField] public int value;
}
Is it normal? How can I save data? I really want to use Undo feature.
Answer by Adam-Mechtley · Jan 06, 2017 at 07:37 AM
Is your Data
class marked with System.Serializable
?
I have the same situation, "Data" class is marked as System.Serializable, but still undo does not record changes to individual array fields..
Answer by warre_engels · Aug 04, 2021 at 09:04 AM
I had the same problem and i already had [System.Serializable]
on my class, for me this link helped.
Basically instead of Undo.RecordObject(object, name)
, you call Undo.RegisterCompleteObjectUndo(object, name)
first, then you change the data and then you call EditorUtility.SetDirty(object)
.
For anyone who still cares after all these years :)