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();_
_ }*_