From 14105785f0c626899de55cf213c7b5646cd68459 Mon Sep 17 00:00:00 2001 From: Sinai Date: Thu, 27 May 2021 19:30:19 +1000 Subject: [PATCH] Fix SceneExplorer not properly detecting scene changes sometimes --- src/UI/ObjectExplorer/SceneExplorer.cs | 12 ++++----- src/UI/ObjectExplorer/SceneHandler.cs | 37 +++++++++++--------------- 2 files changed, 22 insertions(+), 27 deletions(-) diff --git a/src/UI/ObjectExplorer/SceneExplorer.cs b/src/UI/ObjectExplorer/SceneExplorer.cs index 36cc15c..e30ffc4 100644 --- a/src/UI/ObjectExplorer/SceneExplorer.cs +++ b/src/UI/ObjectExplorer/SceneExplorer.cs @@ -39,7 +39,7 @@ namespace UnityExplorer.UI.ObjectExplorer private GameObject refreshRow; private Dropdown sceneDropdown; - private readonly Dictionary sceneToDropdownOption = new Dictionary(); + private readonly Dictionary sceneToDropdownOption = new Dictionary(); private IEnumerable GetRootEntries() => SceneHandler.CurrentRootObjects; @@ -70,7 +70,7 @@ namespace UnityExplorer.UI.ObjectExplorer var go = transform.gameObject; if (SceneHandler.SelectedScene != go.scene) { - int idx = sceneDropdown.options.IndexOf(sceneToDropdownOption[go.scene.handle]); + int idx = sceneDropdown.options.IndexOf(sceneToDropdownOption[go.scene]); sceneDropdown.value = idx; } @@ -91,12 +91,12 @@ namespace UnityExplorer.UI.ObjectExplorer private void SceneHandler_OnInspectedSceneChanged(Scene scene) { - if (!sceneToDropdownOption.ContainsKey(scene.handle)) + if (!sceneToDropdownOption.ContainsKey(scene)) PopulateSceneDropdown(); - if (sceneToDropdownOption.ContainsKey(scene.handle)) + if (sceneToDropdownOption.ContainsKey(scene)) { - var opt = sceneToDropdownOption[scene.handle]; + var opt = sceneToDropdownOption[scene]; int idx = sceneDropdown.options.IndexOf(opt); if (sceneDropdown.value != idx) sceneDropdown.value = idx; @@ -134,7 +134,7 @@ namespace UnityExplorer.UI.ObjectExplorer var option = new Dropdown.OptionData(name); sceneDropdown.options.Add(option); - sceneToDropdownOption.Add(scene.handle, option); + sceneToDropdownOption.Add(scene, option); } } diff --git a/src/UI/ObjectExplorer/SceneHandler.cs b/src/UI/ObjectExplorer/SceneHandler.cs index c6f3538..527c849 100644 --- a/src/UI/ObjectExplorer/SceneHandler.cs +++ b/src/UI/ObjectExplorer/SceneHandler.cs @@ -18,7 +18,7 @@ namespace UnityExplorer.UI.ObjectExplorer get => m_selectedScene; internal set { - if (m_selectedScene != null && m_selectedScene?.handle == value?.handle) + if (m_selectedScene != null && m_selectedScene == value) return; m_selectedScene = value; OnInspectedSceneChanged?.Invoke((Scene)m_selectedScene); @@ -37,6 +37,7 @@ namespace UnityExplorer.UI.ObjectExplorer /// public static ReadOnlyCollection LoadedScenes => new ReadOnlyCollection(allLoadedScenes); private static readonly List allLoadedScenes = new List(); + private static HashSet previousLoadedScenes; /// /// The names of all scenes in the build settings, if they could be retrieved. @@ -82,7 +83,7 @@ namespace UnityExplorer.UI.ObjectExplorer } private static GameObject dontDestroyObject; - public static bool InspectingAssetScene => !SelectedScene?.IsValid() ?? false; + public static bool InspectingAssetScene => SelectedScene.HasValue && SelectedScene.Value == default; internal static void Init() { @@ -110,17 +111,9 @@ namespace UnityExplorer.UI.ObjectExplorer internal static void Update() { - int curHandle = SelectedScene?.handle ?? -1; - // DontDestroyOnLoad always exists, so default to true if our curHandle is that handle. - // otherwise we will check while iterating. - bool inspectedExists = curHandle == DontDestroyHandle || curHandle == 0; - - // Quick sanity check if the loaded scenes changed - bool anyChange = LoadedSceneCount != allLoadedScenes.Count; - // otherwise keep a lookup table of the previous handles to check if the list changed at all. - HashSet previousHandles = null; - if (!anyChange) - previousHandles = new HashSet(allLoadedScenes.Select(it => it.handle)); + // check if the loaded scenes changed. always confirm DontDestroy / HideAndDontSave + int confirmedCount = 2; + bool inspectedExists = SelectedScene == DontDestroyScene || (SelectedScene.HasValue && SelectedScene.Value == default); allLoadedScenes.Clear(); @@ -130,20 +123,22 @@ namespace UnityExplorer.UI.ObjectExplorer if (scene == default || !scene.isLoaded) continue; - // If no changes yet, ensure the previous list contained this handle. - if (!anyChange && !previousHandles.Contains(scene.handle)) - anyChange = true; + // 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 (curHandle != -1 && !inspectedExists && scene.handle == curHandle) + if (!inspectedExists && scene == SelectedScene) inspectedExists = true; allLoadedScenes.Add(scene); } - // Always add the DontDestroyOnLoad scene and the "none" scene. + bool anyChange = confirmedCount != allLoadedScenes.Count; + allLoadedScenes.Add(DontDestroyScene); allLoadedScenes.Add(default); + previousLoadedScenes = new HashSet(allLoadedScenes); // Default to first scene if none selected or previous selection no longer exists. if (!inspectedExists) @@ -163,14 +158,14 @@ namespace UnityExplorer.UI.ObjectExplorer else { var allObjects = RuntimeProvider.Instance.FindObjectsOfTypeAll(typeof(GameObject)); - var list = new List(); + var objects = new List(); foreach (var obj in allObjects) { var go = obj.TryCast(); if (go.transform.parent == null && !go.scene.IsValid()) - list.Add(go); + objects.Add(go); } - rootObjects = list.ToArray(); + rootObjects = objects.ToArray(); } } }