CreateEditor called from OnEnable and fails.

I have a custom editor, and that custom editor is calling Editor.CreateEditor from OnEnable (to create a second editor). In the editor, this works fine, but when I start the game, I get two exceptions: first a null reference, then an invalid cast. Here are the stack traces for each:

NullReferenceException: Object reference not set to an instance of an object
UnityEditor.CustomEditorAttributes.FindCustomEditorType (UnityEngine.Object o, Boolean multiEdit) (at E:/unity/Unity3D/Editor/Mono/CustomEditorAttributes.cs:48)
UnityEditor.Editor:CreateEditor(Object[])
<EDITOR>:OnEnable() (at <EDITOR>.cs:56)

InvalidCastException: Cannot cast from source type to destination type.
<EDITOR>.OnEnable () (at <EDITOR>.cs:56)

It would seem that OnEnable is called a second time after the first failure. Everything works after that, but it still leaves me with random error messages. I’m working with other people, so I’d rather not have those. Edit: The first editor is for a class with the ExecuteInEditMode attribute, which may be causing the two calls.

The first editor does not support multi-edit, but the second does, and CreateEditor is being called with an array of Objects. I have already checked to make sure that the array is not null, and that none of the Objects are null.

I just ran into this too. It turns out there is a bug in Unity’s custom editor management code.

The Unity Editor will reload your C# assembly when (a) you make a code change and the assembly gets recompiled, and (b) when you enter or exit play mode. This assembly reloading also applies to the UnityEditor DLL. Very similar to the hoops we need to jump through to support live code editing, the Unity Editor must jump through similar hoops to maintain state during assembly reloads.

As it happens, they missed one case – UnityEditor.EditorAssemblies is an internal class that keeps a list of loadedAssemblies. This list is used by the FindCustomEditorType method of UnityEditor.CustomEditorAttributes (another internal class). The list of loadedAssemblies is rescanned when UnityEditor.CustomEditorAttributes.s_Initialized is false. Unfortunately this flag is false when your custom editor’s OnEnable method is called, and even worse, the list of loadedAssemblies is null. CustomEditorAttributes attempts to access the null list of loadedAssemblies, and boom, the NullReferenceException gets thrown.

My workaround was to not call CreateEditor from OnEnable, but just set a flag indicating I need to update the editor. Then in OnInspectorGUI I check the flag and if it is set then I get the editor (and clear the flag), like so:

public class MyEditor : Editor
{
    Editor mOtherEditor = null;
    bool mOtherEditorUpdateNeeded = false;

    private void OnEnable()
    {
        mOtherEditor = null;
        mOtherEditorUpdateNeeded = true;
    }

    public override void OnInspectorGUI ()
    {
        if (mOtherEditorUpdateNeeded)
        {
            mOtherEditorUpdateNeeded = false;
            mOtherEditor = Editor.CreateEditor(someOtherObject);
        }
        // etc.
    }