Fix issue with partially unloaded scenes(?)

This commit is contained in:
Sinai 2022-03-03 03:22:17 +11:00
parent 4e76eca73a
commit 79f2514109
2 changed files with 20 additions and 27 deletions

View File

@ -27,7 +27,7 @@ namespace UnityExplorer.ObjectExplorer
Parent = parent; Parent = parent;
SceneHandler.OnInspectedSceneChanged += SceneHandler_OnInspectedSceneChanged; SceneHandler.OnInspectedSceneChanged += SceneHandler_OnInspectedSceneChanged;
SceneHandler.OnLoadedScenesChanged += SceneHandler_OnLoadedScenesChanged; SceneHandler.OnLoadedScenesUpdated += SceneHandler_OnLoadedScenesUpdated;
} }
public override GameObject UIRoot => uiRoot; public override GameObject UIRoot => uiRoot;
@ -87,7 +87,7 @@ namespace UnityExplorer.ObjectExplorer
Tree.JumpAndExpandToTransform(transform); Tree.JumpAndExpandToTransform(transform);
} }
private void OnDropdownChanged(int value) private void OnSceneSelectionDropdownChanged(int value)
{ {
if (value < 0 || SceneHandler.LoadedScenes.Count <= value) if (value < 0 || SceneHandler.LoadedScenes.Count <= value)
return; return;
@ -101,7 +101,7 @@ namespace UnityExplorer.ObjectExplorer
private void SceneHandler_OnInspectedSceneChanged(Scene scene) private void SceneHandler_OnInspectedSceneChanged(Scene scene)
{ {
if (!sceneToDropdownOption.ContainsKey(scene)) if (!sceneToDropdownOption.ContainsKey(scene))
PopulateSceneDropdown(); PopulateSceneDropdown(SceneHandler.LoadedScenes);
if (sceneToDropdownOption.ContainsKey(scene)) if (sceneToDropdownOption.ContainsKey(scene))
{ {
@ -122,17 +122,17 @@ namespace UnityExplorer.ObjectExplorer
refreshRow.SetActive(!scene.IsValid()); refreshRow.SetActive(!scene.IsValid());
} }
private void SceneHandler_OnLoadedScenesChanged(List<Scene> loadedScenes) private void SceneHandler_OnLoadedScenesUpdated(List<Scene> loadedScenes)
{ {
PopulateSceneDropdown(); PopulateSceneDropdown(loadedScenes);
} }
private void PopulateSceneDropdown() private void PopulateSceneDropdown(List<Scene> loadedScenes)
{ {
sceneToDropdownOption.Clear(); sceneToDropdownOption.Clear();
sceneDropdown.options.Clear(); sceneDropdown.options.Clear();
foreach (var scene in SceneHandler.LoadedScenes) foreach (var scene in loadedScenes)
{ {
if (sceneToDropdownOption.ContainsKey(scene)) if (sceneToDropdownOption.ContainsKey(scene))
continue; continue;
@ -198,11 +198,11 @@ namespace UnityExplorer.ObjectExplorer
var dropLabel = UIFactory.CreateLabel(dropRow, "SelectorLabel", "Scene:", TextAnchor.MiddleLeft, Color.cyan, false, 15); var dropLabel = UIFactory.CreateLabel(dropRow, "SelectorLabel", "Scene:", TextAnchor.MiddleLeft, Color.cyan, false, 15);
UIFactory.SetLayoutElement(dropLabel.gameObject, minHeight: 25, minWidth: 60, flexibleWidth: 0); UIFactory.SetLayoutElement(dropLabel.gameObject, minHeight: 25, minWidth: 60, flexibleWidth: 0);
var dropdownObj = UIFactory.CreateDropdown(dropRow, "SceneDropdown", out sceneDropdown, "<notset>", 13, OnDropdownChanged); var dropdownObj = UIFactory.CreateDropdown(dropRow, "SceneDropdown", out sceneDropdown, "<notset>", 13, OnSceneSelectionDropdownChanged);
UIFactory.SetLayoutElement(dropdownObj, minHeight: 25, flexibleHeight: 0, flexibleWidth: 9999); UIFactory.SetLayoutElement(dropdownObj, minHeight: 25, flexibleHeight: 0, flexibleWidth: 9999);
SceneHandler.Update(); SceneHandler.Update();
PopulateSceneDropdown(); PopulateSceneDropdown(SceneHandler.LoadedScenes);
sceneDropdown.captionText.text = sceneToDropdownOption.First().Value.text; sceneDropdown.captionText.text = sceneToDropdownOption.First().Value.text;
// Filter row // Filter row

View File

@ -17,10 +17,11 @@ namespace UnityExplorer.ObjectExplorer
get => selectedScene; get => selectedScene;
internal set internal set
{ {
if (selectedScene != null && selectedScene == value) if (selectedScene.HasValue && selectedScene == value)
return; return;
selectedScene = value; selectedScene = value;
OnInspectedSceneChanged?.Invoke((Scene)selectedScene); OnInspectedSceneChanged?.Invoke((Scene)selectedScene);
ExplorerCore.Log($"Set selected scene to {value?.name}");
} }
} }
private static Scene? selectedScene; private static Scene? selectedScene;
@ -30,7 +31,7 @@ namespace UnityExplorer.ObjectExplorer
/// <summary>All currently loaded Scenes.</summary> /// <summary>All currently loaded Scenes.</summary>
public static List<Scene> LoadedScenes { get; private set; } = new(); public static List<Scene> LoadedScenes { get; private set; } = new();
private static HashSet<Scene> previousLoadedScenes; //private static HashSet<Scene> previousLoadedScenes;
/// <summary>The names of all scenes in the build settings, if they could be retrieved.</summary> /// <summary>The names of all scenes in the build settings, if they could be retrieved.</summary>
public static List<string> AllSceneNames { get; private set; } = new(); public static List<string> AllSceneNames { get; private set; } = new();
@ -39,7 +40,7 @@ namespace UnityExplorer.ObjectExplorer
public static event Action<Scene> OnInspectedSceneChanged; public static event Action<Scene> OnInspectedSceneChanged;
/// <summary>Invoked whenever the list of currently loaded Scenes changes. The argument contains all loaded scenes after the change.</summary> /// <summary>Invoked whenever the list of currently loaded Scenes changes. The argument contains all loaded scenes after the change.</summary>
public static event Action<List<Scene>> OnLoadedScenesChanged; public static event Action<List<Scene>> OnLoadedScenesUpdated;
/// <summary>Generally will be 2, unless DontDestroyExists == false, then this will be 1.</summary> /// <summary>Generally will be 2, unless DontDestroyExists == false, then this will be 1.</summary>
internal static int DefaultSceneCount => 1 + (DontDestroyExists ? 1 : 0); internal static int DefaultSceneCount => 1 + (DontDestroyExists ? 1 : 0);
@ -84,23 +85,20 @@ namespace UnityExplorer.ObjectExplorer
internal static void Update() internal static void Update()
{ {
// check if the loaded scenes changed. always confirm DontDestroy / HideAndDontSave // Inspected scene will exist if it's DontDestroyOnLoad or HideAndDontSave
int confirmedCount = DefaultSceneCount; bool inspectedExists =
bool inspectedExists = (SelectedScene.HasValue && SelectedScene.Value.handle == -12) SelectedScene.HasValue
|| (SelectedScene.HasValue && SelectedScene.Value.handle == -1); && ((DontDestroyExists && SelectedScene.Value.handle == -12)
|| SelectedScene.Value.handle == -1);
LoadedScenes.Clear(); LoadedScenes.Clear();
for (int i = 0; i < SceneManager.sceneCount; i++) for (int i = 0; i < SceneManager.sceneCount; i++)
{ {
Scene scene = SceneManager.GetSceneAt(i); Scene scene = SceneManager.GetSceneAt(i);
if (scene == default || !scene.isLoaded) if (scene == default || !scene.isLoaded || !scene.IsValid())
continue; continue;
// If no changes yet, ensure the previous list contained the scene
if (previousLoadedScenes != null && previousLoadedScenes.Contains(scene))
confirmedCount++;
// If we have not yet confirmed inspectedExists, check if this scene is our currently inspected one. // If we have not yet confirmed inspectedExists, check if this scene is our currently inspected one.
if (!inspectedExists && scene == SelectedScene) if (!inspectedExists && scene == SelectedScene)
inspectedExists = true; inspectedExists = true;
@ -112,17 +110,12 @@ namespace UnityExplorer.ObjectExplorer
LoadedScenes.Add(new Scene { m_Handle = -12 }); LoadedScenes.Add(new Scene { m_Handle = -12 });
LoadedScenes.Add(new Scene { m_Handle = -1 }); LoadedScenes.Add(new Scene { m_Handle = -1 });
bool anyChange = confirmedCount != LoadedScenes.Count;
previousLoadedScenes = new HashSet<Scene>(LoadedScenes);
// Default to first scene if none selected or previous selection no longer exists. // Default to first scene if none selected or previous selection no longer exists.
if (!inspectedExists) if (!inspectedExists)
SelectedScene = LoadedScenes.First(); SelectedScene = LoadedScenes.First();
// Notify on the list changing at all // Notify on the list changing at all
if (anyChange) OnLoadedScenesUpdated?.Invoke(LoadedScenes);
OnLoadedScenesChanged?.Invoke(LoadedScenes);
// Finally, update the root objects list. // Finally, update the root objects list.
if (SelectedScene != null && ((Scene)SelectedScene).IsValid()) if (SelectedScene != null && ((Scene)SelectedScene).IsValid())