Search Unity

  1. Unity Asset Manager is now available in public beta. Try it out now and join the conversation here in the forums.
    Dismiss Notice

Array element deletion change

Discussion in '2021.2 Beta' started by Baste, Feb 18, 2021.

  1. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,334
    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.
     
    mahdi_jeddi, LeonhardP and Xarbrough like this.
  2. TomasKucinskas

    TomasKucinskas

    Unity Technologies

    Joined:
    Dec 20, 2017
    Posts:
    60
    Yes, Baste. You will no longer have to worry about DeleteArrayElementAtIndex nulling references instead of deleting them.
     
  3. Xarbrough

    Xarbrough

    Joined:
    Dec 11, 2014
    Posts:
    1,188
    That's a welcome change!
     
  4. Peter77

    Peter77

    QA Jesus

    Joined:
    Jun 12, 2013
    Posts:
    6,609
    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.
     
  5. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,334
    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:

    Code (csharp):
    1. void DeleteElementAtIndexFromArray(SerializedProperty array, int index) {
    2.     // skip checks for "is this actually an array" and "is index in range"
    3.  
    4.     // version 1:
    5.     var elementToDelete = array.GetArrayElementAtIndex(index);
    6.     if (elementToDelete.propertyType == SerializedPropertyType.ObjectReference)
    7.         elementToDelete.objectReferenceValue = null;
    8.     array.DeleteArrayElementAtIndex(index);
    9.  
    10.     //version 2:
    11.     var oldLength = array.arraySize;
    12.     array.DeleteArrayElementAtIndex(index);
    13.     if (array.arraySize == oldLength)
    14.         array.DeleteArrayElementAtIndex(index);
    15. }
    Both of those will still work with the change. Both are also annoying and stupid and only necessary because the old behavior was dumb.
     
  6. singlis

    singlis

    Joined:
    Oct 29, 2018
    Posts:
    3
    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.