Search Issue Tracker

By Design

Votes

0

Found in

2019.4

2020.1.3f1

2020.2

Issue ID

1273775

Regression

No

Increasing size of a serialized array in the Inspector sends draw call for new object before inserting it into the array

IMGUI

-

How to reproduce:
1. Open the attached '1273775.zip' project
2. From the 'Scenes' folder open the 'SampleScene' Scene
3. In the Hierarchy window select the 'Main Camera' object
4. In the Inspector window extract the 'Example Classes' field
5. Set the 'Size' value to 2
6. Observe the console

Expected result: The value is inserted, no visible errors present
Actual result: The IndexOutOfRangeException error is shown

Reproducible with: 2019.4.9f1, 2020.1.4f1, 2020.2.0a21, 2020.2.0b2
Cannot test with: 2018.4.27f1 (due to errors)

  1. Resolution Note:

    Hi thanks for your bug report regarding `Increasing size of a serialized array in the Inspector sends draw call for new object before inserting it into the array`.
    After further investigation I can say that this behaviour is by design. You are working with both the SerializedProperty and the object instance, these 2 go out of sync when a change is made and will not resync until the changes are applied with ApplyModifiedProperties which is called by the Editor at the end of the GUI update.

    The GUI is being updated starting at the top and working down, this means we first do the array size field and then draw the items with the PropertyDrawers. So if the array size is changed during the update then the SerializedProperty will not have flushed the changes to the instance as it will still be part of the same update. We don’t force an immediate update to the instance when a value is changed in a SerializedProperty, including array size., this must be done from the Editor. It would not be safe for us to do so when the array size is changed as the controlling Editor may not want to have the change recorded and may not want it recorded with Undo support.

    For your use case I would strongly advise you to use a SerializedProperty for everything including the ToggleField.
    Changing the OnGUI to this will work

    public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
    {
    var exampleValue = property.FindPropertyRelative("exampleValue");
    EditorGUI.PropertyField(position, exampleValue, label);
    }

    If you must have access to the instance then you can work around it by checking the array size of the serialized property to the actual instance, if they do not match then force an update.
    Adding this into the GetInstanceFromProperty will work

    if (objectArray.Count <= elementIndex)
    {
    property.serializedObject.ApplyModifiedProperties();
    return GetInstanceFromProperty(property);
    }

Add comment

Log in to post comment

All about bugs

View bugs we have successfully reproduced, and vote for the bugs you want to see fixed most urgently.