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 :frowning:
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.

Is your Data class marked with System.Serializable?

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 :slight_smile: