Custom Editor gets created multiple times and receives OnEnable message

I have this weird problem: I have a regular CustomEditor for a component in the scene and in some unknown specific case (maybe on recompile with compile errors) the editor instance gets duplicated in the scene. Now after every recompile or play mode, I get a NullReference exception from the second inspector, because the target property is null. The other instance still works correct.

Has anybody experienced this as well? I’m not sure if I’m doing something terrible somewhere hidden or if its a Unity bug. I can’t reliably reproduce the problem.

Here is some of my code, although I really don’t see any problem.

[CustomEditor(typeof(MapView))]
	public class MapEditor : Editor
	{
		AbstractTool currentTool = new PaintBrush();
		
		GhostPool ghostPool;
		MapView mapView;

		void OnEnable()
		{
			Debug.Log("OnEnable " + GetInstanceID()); // Sometimes I get two different instances at the same time. One of them has a null target.

			// Unity bug? Sometimes a second MapEditor lingers in the scene and receives OnEnable.
			if(this == null || target == null)
				DestroyImmediate(this); // This doesn't work to clean up the leaked instance.

			if (EditorApplication.isPlayingOrWillChangePlaymode)
				return;

			mapView = (MapView)target;
			if (mapView.tileset == null)
				mapView.tileset = Resources.Load<Tileset>("TileSet");
			if (mapView.map == null)
				mapView.map = new TileMap();

			mapView.ClearAndInitialize();
			Undo.undoRedoPerformed += mapView.ClearAndInitialize;

			// Only called when window is created.
			Tools.toolChanged += ToolChanged_Handler;
			Tools.current = Tool.PaintBrush;
			Selection.hoverChanged += HoverChanged_Handler;
			UnityEditor.Tools.current = UnityEditor.Tool.None;

			// Retrieve an existing preview object pool.
			var ghosts = Resources.FindObjectsOfTypeAll<GhostPool>();
			if (ghosts.Length > 0)
			{
				ghostPool = ghosts[0];
				// If something went wrong and we have additional ones, get rid of them.
				for (int i = 1; i < ghosts.Length; i++)
				{
					ghosts*.Cleanup();*

_ DestroyImmediate(ghosts*);_
_
}_
_
}*_

* // Create a new preview object pool if needed.*
* if (ghostPool == null)*
* {*
* var go = EditorUtility.CreateGameObjectWithHideFlags(“Ghost Pool”, HideFlags.DontSave, typeof(GhostPool));*
* ghostPool = go.GetComponent();*
* }*
* }*

* void OnDisable()*
* {*
* if (EditorApplication.isPlaying)*
* return;*

* // When entering play mode, the mapView reference is lost.*
* if (mapView != null)*
* Undo.undoRedoPerformed -= mapView.ClearAndInitialize;*

* if (ghostPool != null)*
* ghostPool.HideAll();*

* Tools.toolChanged -= ToolChanged_Handler;
Selection.hoverChanged -= HoverChanged_Handler;
_
SceneView.RepaintAll();_
_
}*_

Same goes for me. At some point I noticed that any custom editor scripts are in fact created twice in a row (as well as destroyed). Both have a valid InstanceID, which is a proper, negative number.

However, for me the targets are always pointing to the same, correct component.

Currently re-importing project (maybe metadata for my scripts was corrupted or something), will post comment in a moment on how it went.

As a consequence, this issue emerged: https://forum.unity3d.com/threads/error-editor-variables-returning-different-results-in-two-different-functions.445550/#post-2898261

Solved

@Xarbrough, check the thread, the issue was solved. Turns out it was a problem with the layout of Unity. Resetting to default layout (top right corner of unity UI), then restarting solved the issue of double-editor instances

I suppose we could also use a slightly hacky way:

//OnEnable function of our problematic editor
void OnEnable(){
     var remainingBuggedEditors  = Editor.FindObjectsOfType<MyEditor>();

     foreach(var editor in remainingBuggedEditors) {
         if(editor == this){
              continue;
          }
         Editor.DestroyImmediate(editor);
    }//end foreach
}