Search Unity

Property Drawer: SerializedProperty Disappeared!

Discussion in 'Immediate Mode GUI (IMGUI)' started by jister, Apr 25, 2018.

  1. jister

    jister

    Joined:
    Oct 9, 2009
    Posts:
    1,749
    I have a custom serialized class:
    Code (CSharp):
    1. using System.Reflection;
    2. using UnityEngine;
    3. /// <summary>
    4. /// Uses ReflectorDrawer
    5. /// </summary>
    6. [System.Serializable]
    7. public class Reflector
    8. {
    9.     public GameObject m_Object;
    10.     public Component[] m_Components;
    11.     public MethodInfo[] m_Methods;
    12.     public FieldInfo[] m_Fields;
    13.     public PropertyInfo[] m_Properties;
    14.  
    15.     public int m_CIndex;
    16.     public int m_MIndex;
    17.     public int m_FIndex;
    18.     public int m_PIndex;
    19.  
    20.     public MethodInfo m_GetMethod { get { if( m_MIndex >= 0 ) return m_Methods[m_MIndex]; else return null; } }
    21.     public FieldInfo m_GetField { get { if( m_FIndex >= 0 ) return m_Fields[m_FIndex]; else return null; } }
    22.     public PropertyInfo m_GetProperty { get { if( m_PIndex >= 0 ) return m_Properties[m_PIndex]; else return null; } }
    23.  
    24.     public object m_GetFieldValue { get { return m_GetField.GetValue( m_Components[m_CIndex] ); } }
    25.     public object m_GetPropertyValue { get { return m_GetProperty.GetValue( m_Components[m_CIndex], null ); } }
    26.  
    27.     public Reflector( )
    28.     {
    29.         m_Object = null;
    30.         m_CIndex = m_MIndex = m_FIndex = m_PIndex = -1;
    31.     }
    32. }
    with this as the Drawer:
    Code (CSharp):
    1. using UnityEditor;
    2. using UnityEngine;
    3. using System.Reflection;
    4. using System;
    5. /// <summary>
    6. /// Uses HelperUtility
    7. /// </summary>
    8. [CustomPropertyDrawer( typeof( Reflector ), true )]
    9. public class ReflectorDrawer : PropertyDrawer
    10. {
    11.     Reflector reflector;
    12.     int y;
    13.     GameObject prevObj = null;
    14.     int cInt = -1;
    15.     object parent;
    16.     Component[] components;
    17.     MethodInfo[] methods;
    18.     FieldInfo[] fields;
    19.     PropertyInfo[] properties;
    20.  
    21.     public override float GetPropertyHeight( SerializedProperty property, GUIContent label )
    22.     {
    23.         return base.GetPropertyHeight( property, label ) + y;
    24.     }
    25.  
    26.     public override void OnGUI( Rect position, SerializedProperty property, GUIContent label )
    27.     {
    28.         EditorGUI.BeginProperty( position, label, property );
    29.         {
    30.             property.serializedObject.Update( );
    31.             EditorGUI.HelpBox( new Rect( position.x, position.y, position.width, position.height ), "Reflect On Object", MessageType.None );
    32.             SerializedProperty m_Object = property.FindPropertyRelative( "m_Object" );
    33.             EditorGUI.PropertyField( new Rect( position.x, position.y + 15, position.width, 16 ), m_Object );
    34.             if( m_Object == null )
    35.                 return;
    36.             GameObject obj = (GameObject)m_Object.objectReferenceValue;
    37.             if( obj )
    38.             {
    39.                 SerializedProperty cIndex = property.FindPropertyRelative( "m_CIndex" );
    40.                 SerializedProperty mIndex = property.FindPropertyRelative( "m_MIndex" );
    41.                 SerializedProperty fIndex = property.FindPropertyRelative( "m_FIndex" );
    42.                 SerializedProperty pIndex = property.FindPropertyRelative( "m_PIndex" );
    43.                 if( obj != prevObj )
    44.                 {
    45.                     components = obj.GetComponents<Component>( );
    46.                     cIndex.intValue = mIndex.intValue = fIndex.intValue = pIndex.intValue = 0;
    47.                     Reflect( cIndex.intValue );
    48.                     prevObj = obj;
    49.                 }
    50.                 y = 100;
    51.                 if( cInt != cIndex.intValue )
    52.                 {
    53.                     components = obj.GetComponents<Component>( );
    54.                     mIndex.intValue = fIndex.intValue = pIndex.intValue = 0;
    55.                     Reflect( cIndex.intValue );
    56.                     cInt = cIndex.intValue;
    57.                 }
    58.                 cIndex.intValue = EditorGUI.Popup( new Rect( position.x, position.y + 35, position.width, 15 ), cIndex.intValue, HelperUtility.ToStringArray<Component>( components ) );
    59.                 if( components[cIndex.intValue] != null )
    60.                 {
    61.                     if( methods.Length > 0 )
    62.                     {
    63.                         mIndex.intValue = EditorGUI.Popup( new Rect( position.x, position.y + 55, position.width, 15 ), mIndex.intValue, HelperUtility.ToStringArray<MethodInfo>( methods ) );
    64.                         MethodInfo method = methods[mIndex.intValue];
    65.                         //method.
    66.                     }
    67.                     else
    68.                     {
    69.                         EditorGUI.LabelField( new Rect( position.x, position.y + 55, position.width, 15 ), new GUIContent( "No Methods found on this Type" ), EditorStyles.miniBoldLabel );
    70.                     }
    71.                     if( fields.Length > 0 )
    72.                     {
    73.                         fIndex.intValue = EditorGUI.Popup( new Rect( position.x, position.y + 75, position.width * 0.5f, 15 ), fIndex.intValue, HelperUtility.ToStringArray<FieldInfo>( fields ) );
    74.                         object fieldValue = fields[fIndex.intValue].GetValue( components[cIndex.intValue] );
    75.                         EditorGUI.LabelField( new Rect( position.x + position.width * 0.5f, position.y + 75, position.width * 0.5f, 15 ), new GUIContent( " : " + fieldValue ), EditorStyles.miniBoldLabel );
    76.                     }
    77.                     else
    78.                     {
    79.                         EditorGUI.LabelField( new Rect( position.x, position.y + 75, position.width, 15 ), new GUIContent( "No Fields found on this Type" ), EditorStyles.miniBoldLabel );
    80.                     }
    81.                     if( properties.Length > 0 )
    82.                     {
    83.                         pIndex.intValue = EditorGUI.Popup( new Rect( position.x, position.y + 95, position.width * 0.5f, 15 ), pIndex.intValue, HelperUtility.ToStringArray<PropertyInfo>( properties ) );
    84.                         object propValue = properties[pIndex.intValue].GetValue( components[cIndex.intValue], null );
    85.                         EditorGUI.LabelField( new Rect( position.x + position.width * 0.5f, position.y + 95, position.width * 0.5f, 15 ), new GUIContent( " : " + propValue ), EditorStyles.miniBoldLabel );
    86.                     }
    87.                     else
    88.                     {
    89.                         EditorGUI.LabelField( new Rect( position.x, position.y + 95, position.width, 15 ), new GUIContent( "No Properties found on this Type" ), EditorStyles.miniBoldLabel );
    90.                     }
    91.                 }
    92.             }
    93.             else
    94.                 y = 20;
    95.             property.serializedObject.ApplyModifiedProperties( );
    96.         }
    97.         EditorGUI.EndProperty( );
    98.     }
    99.  
    100.     public void Reflect( int index )
    101.     {
    102.         methods = HelperUtility.GetMethods<Component>( components[index] );
    103.         fields = HelperUtility.GetFields<Component>( components[index] );
    104.         properties = HelperUtility.GetProperties<Component>( components[index] );
    105.     }
    106. }
    107.  
    If i just use it as this
    Code (CSharp):
    1. public class ReflectorTest : MonoBehaviour {
    2.  
    3.     public Reflector reflector;
    it works fine.

    but if i try to use it like this and make a Array of AmbientLoop[] in a monobehavior
    Code (CSharp):
    1. [System.Serializable]
    2. public class AmbientLoop
    3. {
    4.     public string clipName;
    5.     public Reflector reflector;
    6.     public AudioClip clip;
    7.     public AudioClip[] m_RandomClips;
    8.     public TimeInDay timeInDay;
    9.  
    10.     public AmbientLoop( )
    11.     {
    12.         reflector = new Reflector( );
    13.     }
    14. }
    if i already had AmbientLoop instances in the list, the property shows up, but if I empty the list in the inspector and try to set a new size i get:
    Code (CSharp):
    1. SerializedProperty m_AmbientLoops.Array.data[0].reflector has disappeared!
    2. UnityEditor.SerializedProperty:FindPropertyRelative(String)
    3. ReflectorDrawer:OnGUI(Rect, SerializedProperty, GUIContent) (at Assets/Scripts/Misc/Editor/ReflectorDrawer.cs:32)
    4. UnityEngine.GUIUtility:ProcessEvent(Int32, IntPtr)
    5.  
    my guess is the AmbientLoop instance isn't draw yet but it already tries to draw the reflector??
     
  2. N4ma3

    N4ma3

    Joined:
    Nov 1, 2017
    Posts:
    3
    Did you ever find a solution to this problem?

    I'm facing the same thing right now, and it's really confusing...
    There's no documentation on that point, and that doesn't really seem to make any sense.

    So yeah if you succeed to fix this, I would love to know how you did.
     
  3. N4ma3

    N4ma3

    Joined:
    Nov 1, 2017
    Posts:
    3
    Nervermind, I figured it out...

    We don't seem to have the exact same issue, but well the exception thrown was the same.
    So long story short, my problem was because I was manually modifying the size of an Array Serialized Property through the field property.arraySize, but I wasn't applying the modification to the object with property.serializedObject.ApplyModifiedProperties().

    Because I was trying to access the element of the property that comes from the new arraySize, but the object wasn't updated, I was accessing something that doesn't exist yet.
    Well I guess it's something like that, I don't know if I really make sense, but well the fix was this :

    Code (CSharp):
    1. EditorGUI.BeginChangeCheck();
    2.            
    3. property.arraySize = Mathf.Max(0, EditorGUILayout.DelayedIntField("Size", property.arraySize));
    4.            
    5. if (EditorGUI.EndChangeCheck())
    6.         property.serializedObject.ApplyModifiedProperties();
     
    ProGameDevUser and AdamBebko like this.
  4. Plague_Agent

    Plague_Agent

    Joined:
    Jun 19, 2022
    Posts:
    2
    Same thing happened to me, I added a layer mask, and got that error. I removed the layer mask but it still said the same thing.
    Edit: Fix I just exited the project and did not save the change I made that caused the error.
     
  5. DanSolo84

    DanSolo84

    Joined:
    Jan 17, 2019
    Posts:
    1
    Just had this error in unity 2022 , discovered it came from adding a button to a script by dragging to a serialised filed, problem resolved when I changed the button Transition to None, dunno if this will help any else but it was driving me slightly mad!!
     
    Oleksii_Koba likes this.
  6. montster27

    montster27

    Joined:
    Feb 5, 2015
    Posts:
    2
    I had this exact same issue, and it fixed itself when I closed and reopened the project. Everything was saved, Unity was just being dumb
     
    berzerk-fx likes this.
  7. hensoup

    hensoup

    Joined:
    Jan 13, 2014
    Posts:
    35
    just had this problem lately in 2022.3 LTS never had this before with adding and removing items could it be a bug in 2022?
     
  8. firesightstudios

    firesightstudios

    Joined:
    Mar 29, 2022
    Posts:
    57
    Confirmed same problem in 2022 3.2f1
     
  9. hensoup

    hensoup

    Joined:
    Jan 13, 2014
    Posts:
    35
    Solved it guy being more particular with the Lists variables.
     
  10. OyenPiccio

    OyenPiccio

    Joined:
    Dec 25, 2019
    Posts:
    1
    I had the a similar issue just now, my error seemed to be related to opened lists in the inspector. I have functions in my script to remove items from that list and sometimes when items get removed while the list is open in the inspector I get the error. Closing/minimizing lists in the inspector seemed to work for me. This error might be related to serialized properties that update through script displayed in the inspector/editor GUI.
     
    Last edited: Jul 15, 2023
  11. RRD123

    RRD123

    Joined:
    Aug 24, 2022
    Posts:
    8
    Looks like it's an editor error. It happens only when I select the GameObject where I attached a script with a serialized List.
     
    shravanmuniyoor and ow3n like this.
  12. Skaiji-dev

    Skaiji-dev

    Joined:
    Oct 14, 2020
    Posts:
    1
    Same in 2022.3.5f1
     
    shravanmuniyoor likes this.
  13. Papouth

    Papouth

    Joined:
    Mar 28, 2020
    Posts:
    8

    Thank man, minimize the list work for me !
     
    shravanmuniyoor likes this.
  14. fasyle

    fasyle

    Joined:
    Jul 6, 2023
    Posts:
    1
    This also worked for me.
     
    shravanmuniyoor likes this.
  15. temredalert3

    temredalert3

    Joined:
    Jul 20, 2023
    Posts:
    2
    How do we do that?
     
    shravanmuniyoor likes this.
  16. temredalert3

    temredalert3

    Joined:
    Jul 20, 2023
    Posts:
    2
    This helps me. Its surreal how a big engine like this got such an error.
     
    shravanmuniyoor likes this.
  17. Ryziliance

    Ryziliance

    Joined:
    Aug 7, 2023
    Posts:
    1
    Thank you so much, I had the same error where the serializeproperty disspeared, and I selected the gameObject component I changed and it fixed!
     
    shravanmuniyoor likes this.
  18. BarriaKarl

    BarriaKarl

    Joined:
    Jul 30, 2020
    Posts:
    65
    This is crazy.

    Closing and reopening Unity didnt work for me. But closing all Inspector, Debugs, and the likes window did.

    I aint gonna lie, I thought I had bricked my build for a moment there. It was literally unusable since selecting any GO was showing those errors.
     
    shravanmuniyoor likes this.
  19. ow3n

    ow3n

    Joined:
    May 8, 2016
    Posts:
    15
    Collapsing the lists in the inspector worked for me.
     
    shravanmuniyoor and PF-Sebastien like this.
  20. Wilhelm_LAS

    Wilhelm_LAS

    Joined:
    Aug 18, 2020
    Posts:
    55
    It happens when i update a list that shown in inspector and it's annoying...
     
    shravanmuniyoor likes this.
  21. PF-Sebastien

    PF-Sebastien

    Joined:
    Jun 13, 2019
    Posts:
    13

    Hello guys,
    in inspector, i have a serializable object containning lists, and, lists of list.. and i have se same problem !

    close all lists in the inspector and deselect the object that have the script worked for me too.

    Thank a lot for the trick :)
     
    shravanmuniyoor likes this.
  22. simulism

    simulism

    Joined:
    May 11, 2016
    Posts:
    14
    Thank you! I have spent way too much time trying to track down this issue.
     
    shravanmuniyoor likes this.
  23. Dried09

    Dried09

    Joined:
    Jan 2, 2017
    Posts:
    7
    Got this too.
    In my case I have serialized list that updates in runtime (adds and removes new items to/from list)
    And this exception falls to console only in case if GO with this component are opened in the inspector.
    All described workarounds it is good to hide the problem, but the problem is still there.
    I think it is a good case for Unity team to take a look
     
    Botpa and dogustarman like this.
  24. shravanmuniyoor

    shravanmuniyoor

    Joined:
    Mar 1, 2023
    Posts:
    3
    Still the same in 2022.3.9f1
     
  25. alihaydarberkberkberk

    alihaydarberkberkberk

    Joined:
    Jun 13, 2023
    Posts:
    1
    thanks man
     
  26. wingsneon

    wingsneon

    Joined:
    Jul 5, 2018
    Posts:
    23
    I was having the same issue couple hours ago and it was driving me nuts, so here's my solution:
    Just turn all
    public
    lists into
    private
    (only in the script that's causing the error). And if you still want to keep track of the list in the inspector, just make an
    int
    that matches the list's size
    Code (CSharp):
    1.  
    2. private List<GameObject> NearGameobjects = new();
    3. public int listSize;
    4.  
    5. void ListSystem()
    6. {
    7.     //...
    8.     //... function stuff
    9.     //...
    10.     listSize = NearGameobjects.Count //
    11. }
    And if you want to access this list's contents from another script, try workarounds using public methods and public secondary lists.
     
    Last edited: Feb 16, 2024
  27. Alekazam

    Alekazam

    Joined:
    Jun 27, 2022
    Posts:
    7
    I am getting the exact same issue now, I believe it is to do with deleting all variables from an array and then trying to reference them but am still unsure. The error really doesn't explain much.
     
  28. Alekazam

    Alekazam

    Joined:
    Jun 27, 2022
    Posts:
    7
    Thank you so much, I tried this an it instantly fixed the issue. Strange that this causes a problem but who cares if it works lol. Once again thanks so much you saved me hours of searching for answers.
     
    wingsneon likes this.
  29. omachi_vn

    omachi_vn

    Joined:
    Oct 25, 2022
    Posts:
    2
    thank you bro, it working for me, its crazy
     
  30. omachi_vn

    omachi_vn

    Joined:
    Oct 25, 2022
    Posts:
    2
    but has anyone user the 2023 version and has it fixed the error ?
     
  31. Kenthria11

    Kenthria11

    Joined:
    May 6, 2017
    Posts:
    20
    On 2022.3.16f1 (LTS) and still getting this error. De-selecting the object isn't a solution, but an impractical workaround that we shouldn't have to do.
    Please Unity fix this, I need to be able to track my list of custom classes easily.