Search Unity

Why does window fail to load on reboot?

Discussion in 'Scripting' started by ProtagonistKun, Jan 10, 2019.

  1. ProtagonistKun

    ProtagonistKun

    Joined:
    Nov 26, 2015
    Posts:
    352
    Hello,

    I wrote this script trying to make an editor window to hold my items for easy management. But I am running into an issue where every time I close my editor and re-open it, the window does not want to load. Do I need to manually save this somewhere or can someone tell me what I am doing wrong/missing. The data is stored in a scriptable object, but this should not matter. I don't think the way I am storing the data to be displayed inside this window is causing this behaviour.

    I have already looked around on the forum, but I either cannot find a solution or this has not been posted yet (of which the first seems more likely) but I would like to ask for assistance on this matter.

    Thanks in advance.

    Sidenote: general code feedback is always welcome, but keep in mind this is still a work in progress.

    Code (CSharp):
    1. using System;
    2. using Inventory;
    3. using UnityEditor;
    4. using UnityEngine;
    5.  
    6. public class ItemDatabaseWindow : EditorWindow
    7. {
    8.     [MenuItem("Items/Open database")]
    9.     static void Open()
    10.     {
    11.         GetWindow<ItemDatabaseWindow>("Items");
    12.     }
    13.  
    14.     void OnGUI()
    15.     {
    16.        UnityEditor.Editor.CreateEditor(Manager.Instance.ItemContainerObject).OnInspectorGUI();
    17.     }
    18. }
    19.  
    20. [CustomEditor(typeof(ItemDatabase))]
    21. public class ItemDatabaseEditor : UnityEditor.Editor
    22. {
    23.     Vector2 scrollPos = Vector2.zero;
    24.     string searchString = string.Empty;
    25.  
    26.     private enum MouseButton
    27.     {
    28.         LEFT_CLICK = 0,
    29.         RIGHT_CLICK = 1
    30.     }
    31.  
    32.     public override void OnInspectorGUI()
    33.     {
    34.         searchString = EditorHelpers.SearchField(searchString);
    35.  
    36.         scrollPos = GUILayout.BeginScrollView(scrollPos);
    37.         for (int i = 0; i < Manager.Instance.ItemContainerObject.Items.Count; i++)
    38.         {
    39.             var item = Manager.Instance.ItemContainerObject.Items[i].GetComponent<Item>();
    40.             if (!item.ItemName.Contains(searchString, StringComparison.OrdinalIgnoreCase))
    41.             {
    42.                 continue;
    43.             }
    44.  
    45.             if (GUILayout.Button(TextureUtilities.FindTexture(item.ItemSprite), GUIStyle.none, GUILayout.ExpandWidth(false)))
    46.             {
    47.                 GenericMenu currentMenu = new GenericMenu();
    48.  
    49.                 if (Application.isPlaying)
    50.                 {
    51.                     if (Event.current.button == (int)MouseButton.RIGHT_CLICK)
    52.                     {
    53.                         currentMenu.AddItem(new GUIContent("Add to player inventory"), false,
    54.                             () => Manager.Instance.Inventory.GetComponent<Inventory.Inventory>().AddItem(item));
    55.                     }
    56.                 }
    57.                 else
    58.                 {
    59.                     if (Event.current.button == (int)MouseButton.LEFT_CLICK)
    60.                     {
    61.                         Selection.activeGameObject = item.gameObject;
    62.                     }
    63.                     else if (Event.current.button == (int) MouseButton.RIGHT_CLICK)
    64.                     {
    65.                         currentMenu.AddItem(new GUIContent("Remove from database"), false,
    66.                             () => Manager.Instance.ItemContainerObject.RemoveFromList(item.gameObject));
    67.                     }
    68.                 }
    69.  
    70.                 if (currentMenu.GetItemCount() != 0)
    71.                 {
    72.                     currentMenu.ShowAsContext();
    73.                     Event.current.Use();
    74.                 }
    75.             }
    76.         }
    77.         GUILayout.EndScrollView();
    78.     }
    79. }
    80.  
     
  2. ProtagonistKun

    ProtagonistKun

    Joined:
    Nov 26, 2015
    Posts:
    352
    bump, anyone got any leads on this?
     
  3. WallaceT_MFM

    WallaceT_MFM

    Joined:
    Sep 25, 2017
    Posts:
    394
    I would start by looking into
    Manager.Instance.ItemContainerObject
    to see if something is going wrong there; maybe something isn't getting initialized as expected?
     
  4. ProtagonistKun

    ProtagonistKun

    Joined:
    Nov 26, 2015
    Posts:
    352
    Hi there and thx for the suggestion!

    I attached the code of the actual object I am drawing the inspector of. Just in case it would help.
    I double checked the scriptable object as well and the data is correct and saved. The object reference in the manager is also there without an issue.

    However the editor still logs the same message:

    The editor layout could not be fully loaded, this can happen when the layout contains EditorWindows not available in this project
    UnityEditor.WindowLayout:LoadWindowLayout(String, Boolean)

    To me it looks like unity can't find a way to set up the window on a relaunch, not that there is something wrong with what I am providing to this window. Im kinda at a loss here...


    Code (CSharp):
    1. using System;
    2. using System.Collections.Generic;
    3. using UnityEditor;
    4. using UnityEngine;
    5.  
    6. namespace Inventory
    7. {
    8.     [Serializable]
    9.     [CreateAssetMenu(fileName = "Item list", menuName = "Resources/Item list")]
    10.     public class ItemDatabase : ScriptableObject
    11.     {
    12.         public List<GameObject> Items = new List<GameObject>();
    13.  
    14.         public void AddToList(GameObject item)
    15.         {
    16.             Manager.Instance.ItemContainerObject.Items.AddIfNotContains(item);
    17.             EditorUtility.SetDirty(this);
    18.         }
    19.  
    20.         public void AddToList(IEnumerable<GameObject> items)
    21.         {
    22.             foreach (var gameObject in items)
    23.             {
    24.                 AddToList(gameObject);
    25.             }
    26.         }
    27.  
    28.         public void RemoveFromList(GameObject item)
    29.         {
    30.             Items.RemoveIfContains(item);
    31.         }
    32.     }
    33. }
     
  5. xVergilx

    xVergilx

    Joined:
    Dec 22, 2014
    Posts:
    3,296
    Make sure your script filename has the same name as the class.
     
  6. ProtagonistKun

    ProtagonistKun

    Joined:
    Nov 26, 2015
    Posts:
    352
    If it didn't have the same name this would throw an error and tell me to change it doesn't it?
    However I checked this to be sure and they are named the same way, this being respectively
    ItemDatabase.cs and ItemDatabaseEditor.cs

    I have tested moving the window into its own file, however this did not resolve the issue...
     
  7. WallaceT_MFM

    WallaceT_MFM

    Joined:
    Sep 25, 2017
    Posts:
    394
    It sounds like it might be a load order issue, like Unity is trying to load the window layout before your script has been loaded. Are all of your editor scripts in an Editor folder?
     
  8. ProtagonistKun

    ProtagonistKun

    Joined:
    Nov 26, 2015
    Posts:
    352
    upload_2019-1-16_16-20-40.png upload_2019-1-16_16-21-3.png

    Structure of this particular code is

    Item: Prefab with ItemEditor.cs to define its GUI
    ItemDataBase: ScriptableObject holding a list of items with ItemDatabaseEditor and opens the ItemDataBaseEditorWindow

    Code has been provided above already, they are all in the Editor folder, AFAIK subfolders in editor folders are allowed right?

    Could it be I need to change the load order manually or would this be handled by unity?
     
  9. xVergilx

    xVergilx

    Joined:
    Dec 22, 2014
    Posts:
    3,296
    Yes, they are.

    One thing what I might suggest. Try putting a debug before and after the line where your editor window is created. See if the one that afterwards is getting ran.

    If not, maybe it's producing an error and are consumed automatically. E.g. has an NRE.
     
  10. ProtagonistKun

    ProtagonistKun

    Joined:
    Nov 26, 2015
    Posts:
    352
    I put a debug before and after getting the window to call the ItemDatabase.Open() function. (before and after line 11)
    Nothing is popping up except for that message that the layout couldnt be loaded.
     
  11. xVergilx

    xVergilx

    Joined:
    Dec 22, 2014
    Posts:
    3,296
    Have you checked Editor.log?

    Edit: Nvm, it seems you've placed it in a wrong place. Try placing them in OnGUI.

    Open won't be called on editor start anyway.

    This line is a potential trouble:
    > UnityEditor.Editor.CreateEditor(Manager.Instance.ItemContainerObject).OnInspectorGUI();

    User scripts are usually loaded later than editor code. It could be that manager is null during the load.

    Try splitting it one at a time. Like:
    Code (CSharp):
    1. var manager = Manager.Instance;
    2. if (manager == null) {
    3.   // log something
    4.    return;
    5. }
    6.  
    7. // Create editor
    8. // Test created editor
    9.  
    10. // Draw afterwards
    11.  
     
    Last edited: Jan 16, 2019
  12. ProtagonistKun

    ProtagonistKun

    Joined:
    Nov 26, 2015
    Posts:
    352
    Neither the open function nor the OnGUI function seem to be getting called sadly...
    Code (CSharp):
    1. public class ItemDatabaseWindow : EditorWindow
    2. {
    3.     [MenuItem("Items/Open database")]
    4.     static void Open()
    5.     {
    6.         Debug.Log("Before open");
    7.         GetWindow<ItemDatabaseWindow>("Items");
    8.         Debug.Log("After open");
    9.     }
    10.  
    11.     void OnGUI()
    12.     {
    13.         if (Manager.Instance.ItemContainerObject)
    14.         {
    15.             Debug.Log("Manager exists");
    16.         }
    17.  
    18.         Debug.Log("Before GUI");
    19.         UnityEditor.Editor.CreateEditor(Manager.Instance.ItemContainerObject).OnInspectorGUI();
    20.         Debug.Log("After GUI");
    21.     }
    22. }
    If the manager would be null this would throw a nullreference as well, unless that is handled internally by Unity (which i dont think is the case however)
     
  13. WallaceT_MFM

    WallaceT_MFM

    Joined:
    Sep 25, 2017
    Posts:
    394
    Hmm, you could try the process of elimination approach for debugging. Replace all the OnGUI code with something simple like
    Code (csharp):
    1. EditorGUILayout.BeginVertical();
    2. EditorGUILayout.LabelField("This window is being loaded!");
    3. EditorGUILayout.EndVertical();
    If even that doesn't work, then you know that the problem is outside of your code.
     
    xVergilx likes this.
  14. ProtagonistKun

    ProtagonistKun

    Joined:
    Nov 26, 2015
    Posts:
    352
    I tried your idea, with no luck sadly... The window still will not open with a single button on it...

    I am hoping there is someone that might see this post with experience in this that can resolve or at least explain what is going wrong...
     
  15. Are you sure you don't need the reference to your window and the Show() method called in the static method?
    Like in the example in the manual?


    Code (CSharp):
    1.     // Add menu named "My Window" to the Window menu
    2.     [MenuItem("Window/My Window")]
    3.     static void Init()
    4.     {
    5.         // Get existing open window or if none, make a new one:
    6.         MyWindow window = (MyWindow)EditorWindow.GetWindow(typeof(MyWindow));
    7.         window.Show();
    8.     }
    9.  
     
  16. ProtagonistKun

    ProtagonistKun

    Joined:
    Nov 26, 2015
    Posts:
    352
    I tried it, and that didnt work either. The window is open, but if its open and you restart the editor it wont re-open.
    Your suggestion would be more if the window didnt want to open, but thx either way
     
  17. ProtagonistKun

    ProtagonistKun

    Joined:
    Nov 26, 2015
    Posts:
    352
    Not one to revive a dead thread, but I would still like some help with this.
    So bump
     
  18. ProtagonistKun

    ProtagonistKun

    Joined:
    Nov 26, 2015
    Posts:
    352
    bumping again, still looking for an answer on this one
     
  19. ProtagonistKun

    ProtagonistKun

    Joined:
    Nov 26, 2015
    Posts:
    352