Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

OnValidate Creates Unwanted Duplicate Custom EditorWindows

Discussion in 'Editor & General Support' started by M4R5, Jun 24, 2020.

  1. M4R5

    M4R5

    Joined:
    Apr 11, 2013
    Posts:
    33
    2019.3.11f1

    Hey so I've got a custom editor window that implements OnValidate and attempts to refresh itself at runtime and in editor. Here are two examples of it breaking:

    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEditor;
    3.  
    4. [InitializeOnLoad]
    5. public class CustomEditorWindow : EditorWindow
    6. {
    7.    
    8.     public static CustomEditorWindow GetCustomEditorWindow()
    9.     {
    10.         return GetWindow<CustomEditorWindow>();
    11.     }
    12.  
    13.     private static CustomEditorWindow m_Window;
    14.     public static CustomEditorWindow s_Window
    15.     {
    16.         get
    17.         {
    18.             if (m_Window == null)
    19.             {
    20.                 m_Window = GetCustomEditorWindow();
    21.             }
    22.  
    23.             return m_Window;
    24.         }
    25.     }
    26.    
    27.     [MenuItem("Window/Custom Window", false, 200)]
    28.     private static void OpenCustomWindow()
    29.     {
    30.         Debug.Log(s_Window);
    31.     }
    32.  
    33.     private void OnValidate()
    34.     {
    35.         OpenCustomWindow();
    36.     }
    37. }
    38.  


    The above yields duplicate CustomEditorWindows on OnValidate.

    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEditor;
    3.  
    4. [InitializeOnLoad]
    5. public class CustomEditorWindow : EditorWindow
    6. {
    7.    
    8.     public static CustomEditorWindow GetCustomEditorWindow()
    9.     {
    10.         while (((CustomEditorWindow[])Resources.FindObjectsOfTypeAll(typeof(CustomEditorWindow))).Length > 0)
    11.         {
    12.             ((CustomEditorWindow[])Resources.FindObjectsOfTypeAll(typeof(CustomEditorWindow)))[0].Close();
    13.         }
    14.        
    15.         return CreateInstance<CustomEditorWindow>();
    16.     }
    17.  
    18.     private static CustomEditorWindow m_Window;
    19.     public static CustomEditorWindow s_Window
    20.     {
    21.         get
    22.         {
    23.             if (m_Window == null)
    24.             {
    25.                 m_Window = GetCustomEditorWindow();
    26.             }
    27.  
    28.             return m_Window;
    29.         }
    30.     }
    31.    
    32.     [MenuItem("Window/Custom Window", false, 200)]
    33.     private static void OpenCustomWindow()
    34.     {
    35.         Debug.Log(s_Window);
    36.     }
    37.  
    38.     private void OnValidate()
    39.     {
    40.         OpenCustomWindow();
    41.     }
    42. }


    In this case, we'll see a nullref when it gets to the Close function in GetCustomEditorWindow.

    What's interesting is that in printing out the value of the [0] element in FindObjectsOfTypeAll we have found that it is not null.

    Relaunching Unity editor with one of these windows open will also spawn an additional window that exists outside of the original Unity window (ie separate window in the Windows taskbar/dock.) See below:



    Closing the external EditorWindow gives the other one a Failed to Load title.

    Also, the only thing that truly clears 'ghost' windows (when it's saying there's a window open and there clearly is not) is resetting the Layout of the Unity editor at large.
     
  2. M4R5

    M4R5

    Joined:
    Apr 11, 2013
    Posts:
    33
    Here's the screenshot as it looks like the Imgur post failed to link properly.
     
  3. SolleXelloS

    SolleXelloS

    Joined:
    Aug 30, 2010
    Posts:
    17
    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEditor;
    3.  
    4. [InitializeOnLoad]
    5. public class CustomEditorWindow : EditorWindow
    6. {
    7.     private static CustomEditorWindow m_Window;
    8.     public static CustomEditorWindow s_Window
    9.     {
    10.         get
    11.         {
    12.             m_Window = (CustomEditorWindow)CustomEditorWindow.GetWindow(typeof(CustomEditorWindow));//GetCustomEditorWindow();
    13.        
    14.             return m_Window;
    15.         }
    16.     }
    17.  
    18.     [MenuItem("Window/Custom Window", false, 200)]
    19.     private static void OpenCustomWindow()
    20.     {
    21.         Debug.Log(s_Window);
    22.         s_Window.Show();
    23.     }
    24.  
    25.     private void OnValidate()
    26.     {
    27.         OpenCustomWindow();
    28.     }
    29. }