Array element deletion change

From the patch notes:

That’s great, but is this an editor only change, or did you also fix SerializedProperty.DeleteArrayElementAtIndex? Ie. it’s always done what the inspector used to do, causing tons of bugs. If we could call it once instead of setting the object reference value to null first, that’d be a big improvement.

3 Likes

Yes, Baste. You will no longer have to worry about DeleteArrayElementAtIndex nulling references instead of deleting them.

6 Likes

That’s a welcome change!

Please don’t forget to mention this in the upgrade guide, if you haven’t already.

Unless I’m missing something, I’d assume existing code calls DeleteArrayElementAtIndex twice at the moment. With the new behavior in 2021.2, it would then delete the current element and next element, which can be fixed on the user-code side only.

4 Likes

That’d be a bug on the user side right now, since you’d then be clearing the next array element if the slot you were deleting had null in it.

Currently there’s two correct ways to delete an array element:

void DeleteElementAtIndexFromArray(SerializedProperty array, int index) {
    // skip checks for "is this actually an array" and "is index in range"

    // version 1:
    var elementToDelete = array.GetArrayElementAtIndex(index);
    if (elementToDelete.propertyType == SerializedPropertyType.ObjectReference)
        elementToDelete.objectReferenceValue = null;
    array.DeleteArrayElementAtIndex(index);

    //version 2:
    var oldLength = array.arraySize;
    array.DeleteArrayElementAtIndex(index);
    if (array.arraySize == oldLength)
        array.DeleteArrayElementAtIndex(index);
}

Both of those will still work with the change. Both are also annoying and stupid and only necessary because the old behavior was dumb.

4 Likes

We’re using Unity 2020.3.31 and I’m seeing this new behaviour even though it sounds like it was only intended for 2021.2 and beyond. I skimmed the change logs for all of the 2020.3 versions and couldn’t find this specific change, but it may have been called something different. Just a heads up for anyone else looking into why their editor code is behaving strangely. Baste’s suggestions work but I would have preferred to just put the special case code into an #if !UNITY_2021_2_OR_NEWER block.