Find instance of EditorWindow without creating new one?

Hey everybody!

I need to Repaint a specific custom EditorWindow, triggered by changes in a custom inspector. For this I need to find any existing instance of this window.

EditorWindow.FindObjectOfType() does not give me any results at all here…

My current workaround is to create a static pseudo singleton reference to the last EditorWindow, but this is lost once Unity is restarted and not a very elegant way.

GetWindow actually does what you want. It ensures that only one instance is open. When you call GetWindow and the window is already created it reuses the existing window. So just use GetWindow() whenever you need to open the window.

If you want a singleton-like property, just do:

    public static MyEditorWindow Instance
    {
        get { return GetWindow< MyEditorWindow >(); }
    }

If you really just want to find all instances that are open use Resources.FindObjectsOfTypeAll. As mentioned in the docs, be careful since this function can return also internal stuff like the SceneView camera, …

edit
I’ve finally made a base class for MonoBehaviour singletons a couple of days ago. I just made another one for EditorWindow :wink:

// Runtime Extension class
public class MonoBehaviourSingleton< TSelfType > : MonoBehaviour where TSelfType : MonoBehaviour
{
    private static TSelfType m_Instance = null;
    public static TSelfType Instance
    {
        get
        {
            if (m_Instance == null)
            {
                m_Instance = (TSelfType)FindObjectOfType(typeof(TSelfType));
                if (m_Instance == null)
                    m_Instance = (new GameObject(typeof(TSelfType).Name)).AddComponent<TSelfType>();
                DontDestroyOnLoad(m_Instance.gameObject);
            }
            return m_Instance;
        }
    }
}

//Editor Extension class
public class EditorWindowSingleton< TSelfType > : EditorWindow where TSelfType : EditorWindow
{
    private static TSelfType m_Instance = null;
    public static TSelfType FindFirstInstance()
    {
        var windows = (TSelfType[])Resources.FindObjectsOfTypeAll(typeof(TSelfType));
        if (windows.Length == 0)
            return null;
        return windows[0];
    }
    
    public static TSelfType Instance
    {
        get
        {
            if (m_Instance == null)
            {
                m_Instance = FindFirstInstance();
                if (m_Instance == null)
                    m_Instance = GetWindow<TSelfType>();
            }
            return m_Instance;
        }
    }
}

Just derive your class from the singleton base class and your ready to go. You have to pass the type itself as generic parameter. Something like that:

public class MyEditorWindow : EditorWindowSingleton< MyEditorWindow >
{
    //[...]
}

using UnityEngine;
using UnityEditor;

public class MyEditorWindow : EditorWindow {

    #region Window Management
    
    private static MyEditorWindow _instance;

    // And use the property like @Bunny83 suggested
    public static MyEditorWindow Instance {
        get { return GetWindow<MyEditorWindow>(); }
    }

    public static void RepaintWindow() {
        if (_instance != null)
            _instance.Repaint();
    }
    
    #endregion

    void OnEnable() {
        _instance = this;
    }

}

Warning, I haven’t tested the above code, but you should get the idea :slight_smile: