3.1.11: fix potential crash on scene reload

This commit is contained in:
Sinai 2021-03-03 22:09:14 +11:00
parent 2c95fec646
commit 995e2a3e93
3 changed files with 48 additions and 69 deletions

View File

@ -15,7 +15,7 @@ namespace UnityExplorer
public class ExplorerCore public class ExplorerCore
{ {
public const string NAME = "UnityExplorer"; public const string NAME = "UnityExplorer";
public const string VERSION = "3.1.10"; public const string VERSION = "3.1.11";
public const string AUTHOR = "Sinai"; public const string AUTHOR = "Sinai";
public const string GUID = "com.sinai.unityexplorer"; public const string GUID = "com.sinai.unityexplorer";

View File

@ -55,16 +55,15 @@ namespace UnityExplorer.Inspectors
{ {
get get
{ {
if (!m_dontDestroyObject) if (!s_dontDestroyObject)
{ {
m_dontDestroyObject = new GameObject("DontDestroyMe"); s_dontDestroyObject = new GameObject("DontDestroyMe");
GameObject.DontDestroyOnLoad(m_dontDestroyObject); GameObject.DontDestroyOnLoad(s_dontDestroyObject);
} }
return m_dontDestroyObject; return s_dontDestroyObject;
} }
} }
internal static GameObject s_dontDestroyObject;
internal static GameObject m_dontDestroyObject;
public void Init() public void Init()
{ {
@ -97,22 +96,6 @@ namespace UnityExplorer.Inspectors
} }
} }
//#if CPP
// public int GetSceneHandle(string sceneName)
// {
// if (sceneName == "DontDestroyOnLoad")
// return DontDestroyScene;
// for (int i = 0; i < SceneManager.sceneCount; i++)
// {
// var scene = SceneManager.GetSceneAt(i);
// if (scene.name == sceneName)
// return scene.handle;
// }
// return -1;
// }
//#endif
internal void OnSceneChange() internal void OnSceneChange()
{ {
m_sceneDropdown.OnCancel(null); m_sceneDropdown.OnCancel(null);
@ -121,8 +104,13 @@ namespace UnityExplorer.Inspectors
private void RefreshSceneSelector() private void RefreshSceneSelector()
{ {
var names = new List<string>(); var newNames = new List<string>();
var scenes = new List<Scene>(); var newScenes = new List<Scene>();
if (m_currentScenes == null)
m_currentScenes = new Scene[0];
bool anyChange = SceneManager.sceneCount != m_currentScenes.Length - 1;
for (int i = 0; i < SceneManager.sceneCount; i++) for (int i = 0; i < SceneManager.sceneCount; i++)
{ {
@ -131,33 +119,32 @@ namespace UnityExplorer.Inspectors
if (scene == default) if (scene == default)
continue; continue;
scenes.Add(scene); if (!anyChange && !m_currentScenes.Any(it => it.GetHandle() == scene.GetHandle()))
names.Add(scene.name); anyChange = true;
newScenes.Add(scene);
newNames.Add(scene.name);
} }
names.Add("DontDestroyOnLoad"); newNames.Add("DontDestroyOnLoad");
scenes.Add(DontDestroyScene); newScenes.Add(DontDestroyScene);
m_sceneDropdown.options.Clear(); m_sceneDropdown.options.Clear();
foreach (string scene in names) foreach (string scene in newNames)
{ {
m_sceneDropdown.options.Add(new Dropdown.OptionData { text = scene }); m_sceneDropdown.options.Add(new Dropdown.OptionData { text = scene });
} }
if (!names.Contains(m_sceneDropdownText.text)) if (anyChange)
{ {
m_sceneDropdownText.text = names[0]; m_sceneDropdownText.text = newNames[0];
SetTargetScene(scenes[0]); SetTargetScene(newScenes[0]);
} }
m_currentScenes = scenes.ToArray(); m_currentScenes = newScenes.ToArray();
} }
//#if CPP
// public void SetTargetScene(string name) => SetTargetScene(scene.handle);
//#endif
public void SetTargetScene(Scene scene) public void SetTargetScene(Scene scene)
{ {
if (scene == default) if (scene == default)
@ -167,7 +154,7 @@ namespace UnityExplorer.Inspectors
#if CPP #if CPP
GameObject[] rootObjs = SceneUnstrip.GetRootGameObjects(scene.handle); GameObject[] rootObjs = SceneUnstrip.GetRootGameObjects(scene.handle);
#else #else
GameObject[] rootObjs = SceneUnstrip.GetRootGameObjects(scene); GameObject[] rootObjs = scene.GetRootGameObjects();
#endif #endif
SetSceneObjectList(rootObjs); SetSceneObjectList(rootObjs);

View File

@ -3,36 +3,25 @@ using UnityExplorer.Helpers;
using UnityEngine; using UnityEngine;
using UnityEngine.SceneManagement; using UnityEngine.SceneManagement;
using UnityExplorer.Inspectors; using UnityExplorer.Inspectors;
using System.Reflection;
namespace UnityExplorer.Unstrip namespace UnityExplorer.Unstrip
{ {
public class SceneUnstrip public static class SceneUnstrip
{ {
#if MONO #if MONO
public static GameObject[] GetRootGameObjects(Scene scene) => scene.GetRootGameObjects(); private static readonly FieldInfo fi_Scene_handle = typeof(Scene).GetField("m_Handle", ReflectionHelpers.CommonFlags);
//public static GameObject[] GetRootGameObjects(int handle)
//{
// Scene scene = default;
// if (handle == SceneExplorer.DontDestroyHandle)
// scene = SceneExplorer.DontDestroyObject.scene;
// else
// {
// for (int i = 0; i < SceneManager.sceneCount; i++)
// {
// var iscene = SceneManager.GetSceneAt(i);
// if (iscene.handle == handle)
// scene = iscene;
// }
// }
// if (scene != default && scene.handle != -1)
// return scene.GetRootGameObjects();
// return new GameObject[0];
//}
#endif #endif
public static int GetHandle(this Scene scene)
{
#if CPP
return scene.handle;
#else
return (int)fi_Scene_handle.GetValue(scene);
#endif
}
#if CPP #if CPP
//Scene.GetRootGameObjects(); //Scene.GetRootGameObjects();
@ -43,13 +32,16 @@ namespace UnityExplorer.Unstrip
public static GameObject[] GetRootGameObjects(int handle) public static GameObject[] GetRootGameObjects(int handle)
{ {
if (handle == -1) if (handle == -1)
{
return new GameObject[0]; return new GameObject[0];
}
Il2CppSystem.Collections.Generic.List<GameObject> list = new Il2CppSystem.Collections.Generic.List<GameObject>(GetRootCount(handle)); int count = GetRootCount(handle);
d_GetRootGameObjects iCall = ICallHelper.GetICall<d_GetRootGameObjects>("UnityEngine.SceneManagement.Scene::GetRootGameObjectsInternal"); if (count < 1)
return new GameObject[0];
var list = new Il2CppSystem.Collections.Generic.List<GameObject>(count);
var iCall = ICallHelper.GetICall<d_GetRootGameObjects>("UnityEngine.SceneManagement.Scene::GetRootGameObjectsInternal");
iCall.Invoke(handle, list.Pointer); iCall.Invoke(handle, list.Pointer);
@ -58,14 +50,14 @@ namespace UnityExplorer.Unstrip
//Scene.rootCount; //Scene.rootCount;
internal delegate int GetRootCountInternal_delegate(int handle); internal delegate int d_GetRootCountInternal(int handle);
public static int GetRootCount(Scene scene) => GetRootCount(scene.handle); public static int GetRootCount(Scene scene) => GetRootCount(scene.handle);
public static int GetRootCount(int handle) public static int GetRootCount(int handle)
{ {
GetRootCountInternal_delegate iCall = ICallHelper.GetICall<GetRootCountInternal_delegate>("UnityEngine.SceneManagement.Scene::GetRootCountInternal"); return ICallHelper.GetICall<d_GetRootCountInternal>("UnityEngine.SceneManagement.Scene::GetRootCountInternal")
return iCall.Invoke(handle); .Invoke(handle);
} }
#endif #endif
} }