Custom PropertyDrawer causes NullReferenceException

I extracted part of the code I’m working on. It’s is just a simple example of the issue that causes the NullReferenceExcpection.

Basically there is a custom class, which is Serializable and has a custom PropertyDrawer. It is used in a MonoBehaviour, which is just for testing it, which has a variable of that class and an array of that class. The exception is just thrown when you also write a custom Editor for that MonoBehaviour and then start to modify values in the Inspector.

The code works fine with Unity 4.3.1, but fails to work with either Unity 4.5.4 or 4.6.x.
Anyone any idea, why this stopped working?

Here is the code and i also put a package on my dropbox.

MyClass.cs

using UnityEngine;
using System;

[Serializable]
public class MyClass
{
	public string name;
}

MyClassDrawer.cs

using UnityEditor;
using UnityEngine;

[CustomPropertyDrawer( typeof( MyClass ) )]
public class MyClassDrawer : PropertyDrawer
{
	public override void OnGUI( Rect position, SerializedProperty property, GUIContent label )
	{
		SerializedProperty name = property.FindPropertyRelative( "name" );
		
		label = EditorGUI.BeginProperty( position, label, property );
		EditorGUI.PropertyField( position, property.FindPropertyRelative( "name" ) );
		EditorGUI.EndProperty();
	}
}

MyClassTester.cs

using UnityEngine;

public class MyClassTester : MonoBehaviour 
{
	public MyClass myClass;
	public MyClass[] myClassArray;
}

MyClassTesterEditor.cs

using UnityEngine;
using System.Collections;
using UnityEditor;

[CustomEditor( typeof( MyClassTester ) )]
public class MyClassTesterEditor : Editor
{
	public override void OnInspectorGUI()
	{
		serializedObject.Update();
		EditorGUILayout.PropertyField( serializedObject.FindProperty( "myClass" ) );
		EditorGUILayout.PropertyField( serializedObject.FindProperty( "myClassArray" ), true );
		serializedObject.ApplyModifiedProperties();

	}
}

Here is the according stack trace:

NullReferenceException: Object reference not set to an instance of an object
UnityEditor.EditorGUI.BeginProperty (Rect totalPosition, UnityEngine.GUIContent label, UnityEditor.SerializedProperty property) (at C:/BuildAgent/work/d63dfc6385190b60/Editor/Mono/EditorGUI.cs:3859)
UnityEditor.EditorGUI.DefaultPropertyField (Rect position, UnityEditor.SerializedProperty property, UnityEngine.GUIContent label) (at C:/BuildAgent/work/d63dfc6385190b60/Editor/Mono/EditorGUI.cs:4346)
UnityEditor.PropertyHandler.OnGUI (Rect position, UnityEditor.SerializedProperty property, UnityEngine.GUIContent label, Boolean includeChildren) (at C:/BuildAgent/work/d63dfc6385190b60/Editor/Mono/ScriptAttributeGUI/PropertyHandler.cs:144)
UnityEditor.EditorGUI.PropertyFieldInternal (Rect position, UnityEditor.SerializedProperty property, UnityEngine.GUIContent label, Boolean includeChildren) (at C:/BuildAgent/work/d63dfc6385190b60/Editor/Mono/EditorGUI.cs:4341)
UnityEditor.EditorGUI.PropertyField (Rect position, UnityEditor.SerializedProperty property, Boolean includeChildren) (at C:/BuildAgent/work/d63dfc6385190b60/artifacts/EditorGenerated/EditorGUIBindings.cs:698)
UnityEditor.EditorGUI.PropertyField (Rect position, UnityEditor.SerializedProperty property) (at C:/BuildAgent/work/d63dfc6385190b60/artifacts/EditorGenerated/EditorGUIBindings.cs:693)
MyClassDrawer.OnGUI (Rect position, UnityEditor.SerializedProperty property, UnityEngine.GUIContent label) (at Assets/Editor/MyClassDrawer.cs:12)
UnityEditor.PropertyDrawer.OnGUISafe (Rect position, UnityEditor.SerializedProperty property, UnityEngine.GUIContent label) (at C:/BuildAgent/work/d63dfc6385190b60/Editor/Mono/ScriptAttributeGUI/PropertyDrawer.cs:23)
UnityEditor.PropertyHandler.OnGUI (Rect position, UnityEditor.SerializedProperty property, UnityEngine.GUIContent label, Boolean includeChildren) (at C:/BuildAgent/work/d63dfc6385190b60/Editor/Mono/ScriptAttributeGUI/PropertyHandler.cs:134)
UnityEditor.PropertyHandler.OnGUILayout (UnityEditor.SerializedProperty property, UnityEngine.GUIContent label, Boolean includeChildren, UnityEngine.GUILayoutOption[] options) (at C:/BuildAgent/work/d63dfc6385190b60/Editor/Mono/ScriptAttributeGUI/PropertyHandler.cs:195)
UnityEditor.EditorGUILayout.PropertyField (UnityEditor.SerializedProperty property, UnityEngine.GUIContent label, Boolean includeChildren, UnityEngine.GUILayoutOption[] options) (at C:/BuildAgent/work/d63dfc6385190b60/Editor/Mono/EditorGUI.cs:5992)
UnityEditor.EditorGUILayout.PropertyField (UnityEditor.SerializedProperty property, Boolean includeChildren, UnityEngine.GUILayoutOption[] options) (at C:/BuildAgent/work/d63dfc6385190b60/Editor/Mono/EditorGUI.cs:5986)
MyClassTesterEditor.OnInspectorGUI () (at Assets/Editor/MyClassTesterEditor.cs:14)
UnityEditor.InspectorWindow.DrawEditor (UnityEditor.Editor editor, Int32 editorIndex, Boolean forceDirty, System.Boolean& showImportedObjectBarNext, UnityEngine.Rect& importedObjectBarRect, Boolean eyeDropperDirty) (at C:/BuildAgent/work/d63dfc6385190b60/Editor/Mono/Inspector/InspectorWindow.cs:1124)
UnityEditor.DockArea:OnGUI()

The problem here is that your drawer is called both for MyClass and MyClass[]. The first draw at MyClassTesterEditor.cs:11 works great, but the second one at MyClassTesterEditor.cs:12 does not, cause property now contains the actual array, so there’s no name property to look for.

You can check that yourself using modifying your drawer:

using UnityEditor;
using UnityEngine;

[CustomPropertyDrawer (typeof(MyClass))]
public class MyClassDrawer : PropertyDrawer {
	public override void OnGUI (Rect position, SerializedProperty property, GUIContent label) {
		label = EditorGUI.BeginProperty (position, label, property);
		if (property.isArray)
			EditorGUI.PropertyField (position, property, false);
		else
			EditorGUI.PropertyField (position, property.FindPropertyRelative ("name"), false);
		EditorGUI.EndProperty ();
	}
}

I don’t actually know if this behavior has changed after 4.3.1, but maybe after implementing the Decorators on 4.5 they may have changed this API.