Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice

Adding item to List with multiple objects selected throws error when accessing SerializedProperty

Discussion in 'Immediate Mode GUI (IMGUI)' started by keenanwoodall, Feb 1, 2019.

  1. keenanwoodall

    keenanwoodall

    Joined:
    May 30, 2014
    Posts:
    597
    I think this problem may be a little too confusing to explain in text, so I made a video to show the problem and explain everything I've tried. Hopefully someone is familiar with this error. I've been stuck on this error for a couple days and haven't found a single answer online or through my troubleshooting.


    Here's the error:

    Code (CSharp):
    1. InvalidOperationException: The operation is not possible when moved past all properties (Next returned false)
    2. UnityEditor.SerializedProperty.Verify (UnityEditor.SerializedProperty+VerifyFlags verifyFlags) (at C:/buildslave/unity/build/Editor/Mono/SerializedProperty.bindings.cs:330)
    3. UnityEditor.SerializedProperty.FindPropertyRelativeInternal (System.String propertyPath) (at C:/buildslave/unity/build/Editor/Mono/SerializedProperty.bindings.cs:1320)
    4. UnityEditor.SerializedProperty.FindPropertyRelative (System.String relativePropertyPath) (at C:/buildslave/unity/build/Editor/Mono/SerializedProperty.bindings.cs:204)
     
  2. keenanwoodall

    keenanwoodall

    Joined:
    May 30, 2014
    Posts:
    597
    Somehow the object is not being registered as dirty so serializedObject.Update isn't doing anything.

    It's still not completely clear what causes this issue. From what I can tell, it happens when you don't change a field through a SerializedProperty while having multiple objects selected. If you don't use the SerializedProperty, the SerializedObject isn't marked as dirt so calling serializedObject.Update doesn't do anything. You need to call serializedObject.SetIsDifferentCacheDirty() before calling Update which will mark it dirty and in-turn make Update work properly.
     
  3. V0odo0

    V0odo0

    Joined:
    Jan 8, 2012
    Posts:
    328
    For everyone who stuck finding the cause of this error:
    In my case this was caused by iterating over child properties of cached SerializedProperty like this way:
    Code (CSharp):
    1. private SerializedProperty _cachedParentProperty;
    2.  
    3.     void OnEnable()
    4.     {
    5.         _cachedParentProperty = new SerializedObject(myScriptableObject).FindProperty("_myProperty");
    6.     }
    7.  
    8.     void OnGUI()
    9.     {
    10.         foreach (SerializedProperty childProperty in _cachedParentProperty)
    11.         {
    12.             EditorGUILayout.PropertyField(childProperty, true);
    13.         }
    14.     }
    I still no clue why it is happening but getting child properties using FindProperty of SerializedObject inside OnGUI instead of referencing the cached one was solved the issue for me.
    Code (CSharp):
    1. private SerializedObject _serializedObject;
    2.  
    3.     void OnEnable()
    4.     {
    5.         _serializedObject = new SerializedObject(myScriptableObject);
    6.     }
    7.  
    8.     void OnGUI()
    9.     {
    10.         foreach (SerializedProperty childProperty in _serializedObject.FindProperty("_myProperty"))
    11.         {
    12.             EditorGUILayout.PropertyField(childProperty, true);
    13.         }
    14.     }
     
  4. brownboot67

    brownboot67

    Joined:
    Jan 5, 2013
    Posts:
    375
    You might try making those cached properties public or marking them with the SerializeField attribute. If the Editor Window gets rebuilt at any point (it'll happen) those refs would be lost.
     
  5. unity_vhwR5LxKQZuFcg

    unity_vhwR5LxKQZuFcg

    Joined:
    Oct 16, 2018
    Posts:
    2
    Had this problem as well and the solution (regardless of if you're using a cached property or not) is to call:

    Code (CSharp):
    1. serializedObject.SetIsDifferentCacheDirty();
    This was important for my use-case as the button I was clicking was causing each object to be updated with a unique value and the serialized property wasn't getting the memo that the selected objects now had multiple values.
     
    unity_Zof8OuvuZrZIJw likes this.