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

NullReferenceException with SerializedProperty

Discussion in 'Scripting' started by Xillez, Apr 11, 2020.

  1. Xillez

    Xillez

    Joined:
    Sep 5, 2018
    Posts:
    2
    Hey, I have a SerializedProperty called "variables" in "ConditionEditor" class (line 24), that isn't an object instance even though the variable name is directly copied form the file it's in, the editor is a custom editor for "Condition" class plus it is public and serialized. Can anyone tell me what Im missing?

    Error:
    "
    NullReferenceException: Object reference not set to an instance of an object
    UnityEditor.EditorGUILayout.IsChildrenIncluded (UnityEditor.SerializedProperty prop)
    UnityEditor.EditorGUILayout.PropertyField (UnityEditor.SerializedProperty property, UnityEngine.GUILayoutOption[] options)
    EditorUtils.ShowList (UnityEditor.SerializedProperty list, EditorListOption options) (at Assets/Scripts/System/Utils/EditorUtils.cs:14)
    ConditionEditor.OnInspectorGUI () (at Assets/Scripts/System/Utils/Condition/Editor/ConditionEditor.cs:25)
    UnityEditor.UIElements.InspectorElement+<>c__DisplayClass55_0.<CreateIMGUIInspectorFromEditor>b__0 ()
    UnityEngine.GUIUtility: ProcessEvent(Int32, IntPtr)
    "

    ConditionEditor class:
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEditor;
    5.  
    6. [CustomEditor(typeof(Condition))]
    7. public class ConditionEditor : Editor
    8. {
    9.     /*public List<Variable> variables;
    10.     public string expression;*/
    11.  
    12.     private SerializedProperty variables;
    13.     private SerializedProperty expression;
    14.  
    15.     public void OnEnabled()
    16.     {
    17.         this.variables = serializedObject.FindProperty("variables");
    18.         this.expression = serializedObject.FindProperty("expression");
    19.     }
    20.  
    21.     public override void OnInspectorGUI()
    22.     {
    23.         serializedObject.Update();
    24.         EditorUtils.ShowList(this.variables, EditorListOption.Buttons | EditorListOption.NoElementLabels);
    25.         EditorGUILayout.PropertyField(this.expression);
    26.         serializedObject.ApplyModifiedProperties();
    27.     }
    28. }
    Condition class:
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using org.mariuszgromada.math.mxparser;
    5. using org.mariuszgromada.math.mxparser.mathcollection;
    6.  
    7. public class Condition : MonoBehaviour
    8. {
    9.     [SerializeField] public List<Variable> variables = new List<Variable>();
    10.     [SerializeField] public string expression;
    11.  
    12.     public bool Eval()
    13.     {
    14.         // .....
    15.     }
    16. }
    17.  
    Other class used:
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEditor;
    5.  
    6. public class EditorUtils
    7. {
    8.     public static void ShowList(SerializedProperty list, EditorListOption options = EditorListOption.Default)
    9.     {
    10.         bool showListLabel = (options & EditorListOption.ListLabel) != 0;
    11.  
    12.         if (showListLabel)
    13.         {
    14.             EditorGUILayout.PropertyField(list);
    15.             EditorGUI.indentLevel += 1;
    16.         }
    17.  
    18.         if (!showListLabel || list.isExpanded)
    19.                 ShowElements(list, options);
    20.  
    21.         if (showListLabel)
    22.             EditorGUI.indentLevel -= 1;
    23.     }
    24.  
    25.     // List element handling buttons
    26.  
    27.     private static GUIContent moveButtonContent = new GUIContent("\u21b4", "move down");
    28.     private static GUIContent duplicateButtonContent = new GUIContent("+", "duplicate");
    29.     private static GUIContent deleteButtonContent = new GUIContent("-", "delete");
    30.     private static GUIContent addButtonContent = new GUIContent("+", "add element");
    31.  
    32.     private static void ShowElements(SerializedProperty list, EditorListOption options)
    33.     {
    34.         bool showButtons = (options & EditorListOption.Buttons) != 0;
    35.  
    36.         for (int i = 0; i < list.arraySize; i++)
    37.         {
    38.             if (showButtons)
    39.                 EditorGUILayout.BeginHorizontal();
    40.             else
    41.                 EditorGUILayout.PropertyField(list.GetArrayElementAtIndex(i), GUIContent.none);
    42.  
    43.             if (showButtons)
    44.             {
    45.                 ShowElementButtons(list, i);
    46.                 EditorGUILayout.EndHorizontal();
    47.             }
    48.         }
    49.     }
    50.  
    51.     private static GUILayoutOption miniButtonWidth = GUILayout.Width(20f);
    52.  
    53.     private static void ShowElementButtons(SerializedProperty list, int index)
    54.     {
    55.         if (GUILayout.Button(moveButtonContent, EditorStyles.miniButtonLeft, miniButtonWidth))
    56.             list.MoveArrayElement(index, index + 1);
    57.  
    58.         if (GUILayout.Button(duplicateButtonContent, EditorStyles.miniButtonMid, miniButtonWidth))
    59.             list.InsertArrayElementAtIndex(index);
    60.  
    61.         if (GUILayout.Button(deleteButtonContent, EditorStyles.miniButtonRight, miniButtonWidth))
    62.         {
    63.             int oldSize = list.arraySize;
    64.             list.DeleteArrayElementAtIndex(index);
    65.             if (list.arraySize == oldSize)
    66.             {
    67.                 list.DeleteArrayElementAtIndex(index);
    68.             }
    69.         }
    70.     }
    71. }
    72.  
     
  2. PraetorBlue

    PraetorBlue

    Joined:
    Dec 13, 2012
    Posts:
    7,722
    Is it possible that "OnInspectorGUI()" is getting called before "OnEnable()"?
     
  3. PraetorBlue

    PraetorBlue

    Joined:
    Dec 13, 2012
    Posts:
    7,722
    Oh wait, I see the problem! Your "OnEnabled()" method should actually be named "OnEnable()".
     
    Olmi likes this.
  4. Xillez

    Xillez

    Joined:
    Sep 5, 2018
    Posts:
    2
    Thanks a lot! but still gives me the same error for some reason, on the same spot.
    I doubt it to be honest. Hasn't ever happened to me before.
     
  5. bonestormII

    bonestormII

    Joined:
    Apr 24, 2016
    Posts:
    1
    I'm having this exact problem! Have you found the solution yet?
     
  6. mrs26

    mrs26

    Joined:
    Sep 13, 2018
    Posts:
    12
    You need to add the [Serializable] attribute to the "Condition" class. The variables "variables" and "expression" actually don't need the [SerializeField] attribute though, since they are public. Only if you also want to serialize private variables you need to give them that attribute additionally.

    Hope that helps^^
     
    ImFromTheFuture and niki5432 like this.
  7. TomTrottel

    TomTrottel

    Joined:
    Aug 16, 2014
    Posts:
    18
    I think this might be the problem that the array element (or a list) is just cleared and not removed with DeleteArrayElementAtIndex(). (even with the "fix" from the tutorial from catlikecoding you seem to have applied)

    I have the same problem within a custom property drawer. I can delete the last element of the List, which is treated as an serialized array, but if I delete any element than the last, I get "Retrieving array element that was out of bounds" and "NullReferenceException: Object reference not set to an instance of an object".

    [UPDATE]

    So I found this thread : https://forum.unity.com/threads/how...bjects-via-editor-script.479859/#post-3125863

    The static function RemoveElement actually seems to do the trick by setting the property to null (and casting the null to the propertys type ?) then deleting the element. Cause it is empty, the deletion actually works find.
     
    Last edited: Aug 23, 2020
  8. ClockworkBeetle

    ClockworkBeetle

    Joined:
    Apr 5, 2021
    Posts:
    3
    In case some other desperate person ended up here but their error's backtrace, like mine, had no reference to any of their project code...
    I was getting this same basic error (NullReferenceException: Object reference not set to an instance of an object UnityEditor.PropertyHandler.IsArrayReorderable) and restarting Unity made it go away.
     
  9. Mishkawy

    Mishkawy

    Joined:
    Feb 17, 2016
    Posts:
    7
    Can confirm what ClockworkBeetl said. Simply restarting Unity fixes the error.