Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Bug Exception when iterating through a serializedproperty sub elements in the list

Discussion in 'UI Toolkit' started by Florian-Nouviale, May 15, 2023.

  1. Florian-Nouviale

    Florian-Nouviale

    Joined:
    Mar 14, 2013
    Posts:
    51
    Hi,
    I'm trying to display a list of objects using UI Tookit with a custom display based on PeropertyField.
    My main UI (in a class called ScenarioEditorSettingsProvider) has a list that I use to display the elements :

    Code (CSharp):
    1.             SerializedObject serializedInputSettings = new(ScenarioEditorSettingsProfiles.instance);
    2.             SerializedProperty defaultProfilesProperty = serializedInputSettings.FindProperty(nameof(ScenarioEditorSettingsProfiles.DefaultProfiles));
    3.  
    4.             rootElement.Q<ListView>("BaseProfiles").itemsSource = ScenarioEditorSettingsProfiles.instance.DefaultProfiles;
    5.             rootElement.Q<ListView>("BaseProfiles").makeItem = () => new PropertyField();
    6.             rootElement.Q<ListView>("BaseProfiles").bindItem = (e, i) =>
    7.             {
    8.                 (e as PropertyField).BindProperty(defaultProfilesProperty.GetArrayElementAtIndex(i));
    9.             };

    So far so good. Now, I want to change the display of my class using a custom property drawer.

    Code (CSharp):
    1. [CustomPropertyDrawer(typeof(DefaulScenarioEditorSettingsProfile))]
    2.     public class MyCustomProfileDrawer : PropertyDrawer
    3.     {
    4.         public override VisualElement CreatePropertyGUI(SerializedProperty property)
    5.         {
    6.             // Create property container element.
    7.             VisualElement container = new GroupBox();
    8.  
    9.             System.Collections.IEnumerator propertyEnum = property.GetEnumerator();
    10.             while (propertyEnum.MoveNext())
    11.             {
    12.                 SerializedProperty serializedProperty = propertyEnum.Current as SerializedProperty;
    13.                 if (serializedProperty.name == nameof(ScenarioEditorSettingsProfile.Name))
    14.                     continue;
    15.  
    16.                 PropertyField propertyField = new();
    17.                 propertyField.BindProperty(serializedProperty);
    18.                 propertyField.SetEnabled(false);
    19.                 container.Add(propertyField);
    20.             }
    21.             return container;
    22.         }
    23.  
    24.     }
    The code works Except for the last element of my list of objects (Meaning, the last element in "defaultProfilesProperty.GetArrayElementAtIndex(i)"). The last element always fails to display with the following in the console :

    InvalidOperationException: The operation is not possible when moved past all properties (Next returned false)
    UnityEditor.SerializedProperty.Verify (UnityEditor.SerializedProperty+VerifyFlags verifyFlags) (at <5092d70d16a64dd9a555dd50f38aead0>:0)
    UnityEditor.SerializedProperty.FindPropertyRelativeInternal (System.String propertyPath) (at <5092d70d16a64dd9a555dd50f38aead0>:0)
    UnityEditor.SerializedProperty.FindPropertyRelative (System.String relativePropertyPath) (at <5092d70d16a64dd9a555dd50f38aead0>:0)
    UnityEditor.UIElements.Bindings.SerializedObjectBindingContext.BindPropertyRelative (UnityEngine.UIElements.IBindable field, UnityEditor.SerializedProperty parentProperty) (at <963b7b516af945bcb7d30875c64e2e07>:0)
    UnityEditor.UIElements.Bindings.SerializedObjectBindingContext.BindTree (UnityEngine.UIElements.VisualElement element, UnityEditor.SerializedProperty parentProperty) (at <963b7b516af945bcb7d30875c64e2e07>:0)
    UnityEditor.UIElements.Bindings.SerializedObjectBindingContext.BindTree (UnityEngine.UIElements.VisualElement element, UnityEditor.SerializedProperty parentProperty) (at <963b7b516af945bcb7d30875c64e2e07>:0)
    UnityEditor.UIElements.Bindings.SerializedObjectBindingContext.BindTree (UnityEngine.UIElements.VisualElement element, UnityEditor.SerializedProperty parentProperty) (at <963b7b516af945bcb7d30875c64e2e07>:0)
    UnityEditor.UIElements.Bindings.SerializedObjectBindingContext.ContinueBinding (UnityEngine.UIElements.VisualElement element, UnityEditor.SerializedProperty parentProperty) (at <963b7b516af945bcb7d30875c64e2e07>:0)
    UnityEditor.UIElements.Bindings.SerializedObjectBindingContext.Bind (UnityEngine.UIElements.VisualElement element) (at <963b7b516af945bcb7d30875c64e2e07>:0)
    UnityEditor.UIElements.Bindings.DefaultSerializedObjectBindingImplementation.BindProperty (UnityEngine.UIElements.IBindable field, UnityEditor.SerializedProperty property) (at <963b7b516af945bcb7d30875c64e2e07>:0)
    UnityEditor.UIElements.BindingExtensions.BindProperty (UnityEngine.UIElements.IBindable field, UnityEditor.SerializedProperty property) (at <963b7b516af945bcb7d30875c64e2e07>:0)
    Xareus.Unity.Editor.Scenarios.Settings.ScenarioEditorSettingsProvider+<>c__DisplayClass4_0.<OnActivate>b__1 (UnityEngine.UIElements.VisualElement e, System.Int32 i) (at Packages/fr.insa.xareus/Editor/Scenarios/Settings/ScenarioEditorSettingsProvider.cs:69)
    UnityEngine.UIElements.CollectionViewController.BindItem (UnityEngine.UIElements.VisualElement element, System.Int32 index) (at <1aaa12d3c5d64d42836d89caff78b60b>:0)
    UnityEngine.UIElements.CollectionViewController.InvokeBindItem (UnityEngine.UIElements.ReusableCollectionItem reusableItem, System.Int32 index) (at <1aaa12d3c5d64d42836d89caff78b60b>:0)
    UnityEngine.UIElements.ListViewController.InvokeBindItem (UnityEngine.UIElements.ReusableCollectionItem reusableItem, System.Int32 index) (at <1aaa12d3c5d64d42836d89caff78b60b>:0)
    UnityEngine.UIElements.VerticalVirtualizationController`1[T].Setup (T recycledItem, System.Int32 newIndex) (at <1aaa12d3c5d64d42836d89caff78b60b>:0)
    UnityEngine.UIElements.DynamicHeightVirtualizationController`1[T].Fill () (at <1aaa12d3c5d64d42836d89caff78b60b>:0)
    UnityEngine.UIElements.VisualElement+SimpleScheduledItem.PerformTimerUpdate (UnityEngine.UIElements.TimerState state) (at <1aaa12d3c5d64d42836d89caff78b60b>:0)
    UnityEngine.UIElements.TimerEventScheduler.UpdateScheduledEvents () (at <1aaa12d3c5d64d42836d89caff78b60b>:0)
    UnityEngine.UIElements.UIElementsUtility.UnityEngine.UIElements.IUIElementsUtility.UpdateSchedulers () (at <1aaa12d3c5d64d42836d89caff78b60b>:0)
    UnityEngine.UIElements.UIEventRegistration.UpdateSchedulers () (at <1aaa12d3c5d64d42836d89caff78b60b>:0)
    UnityEditor.RetainedMode.UpdateSchedulers () (at <963b7b516af945bcb7d30875c64e2e07>:0)

    I tried different ways of displaying this data but none worked
     
  2. Florian-Nouviale

    Florian-Nouviale

    Joined:
    Mar 14, 2013
    Posts:
    51
  3. C-UITools

    C-UITools

    Unity Technologies

    Joined:
    Jun 23, 2021
    Posts:
    22
    Thank you for reporting it!