2021-05-26 17:41:51 +10:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Collections.ObjectModel;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Text;
|
|
|
|
|
using UnityEngine;
|
|
|
|
|
using UnityEngine.SceneManagement;
|
2021-12-02 18:35:46 +11:00
|
|
|
|
using UniverseLib;
|
2021-05-26 17:41:51 +10:00
|
|
|
|
|
2021-06-30 07:49:58 +10:00
|
|
|
|
namespace UnityExplorer.ObjectExplorer
|
2021-05-26 17:41:51 +10:00
|
|
|
|
{
|
|
|
|
|
public static class SceneHandler
|
|
|
|
|
{
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// The currently inspected Scene.
|
|
|
|
|
/// </summary>
|
2021-06-05 19:36:09 +10:00
|
|
|
|
public static Scene? SelectedScene
|
2021-05-26 17:41:51 +10:00
|
|
|
|
{
|
2021-05-29 14:50:27 +10:00
|
|
|
|
get => selectedScene;
|
2021-05-26 17:41:51 +10:00
|
|
|
|
internal set
|
|
|
|
|
{
|
2021-05-29 14:50:27 +10:00
|
|
|
|
if (selectedScene != null && selectedScene == value)
|
2021-05-26 17:41:51 +10:00
|
|
|
|
return;
|
2021-05-29 14:50:27 +10:00
|
|
|
|
selectedScene = value;
|
|
|
|
|
OnInspectedSceneChanged?.Invoke((Scene)selectedScene);
|
2021-05-26 17:41:51 +10:00
|
|
|
|
}
|
|
|
|
|
}
|
2021-05-29 14:50:27 +10:00
|
|
|
|
private static Scene? selectedScene;
|
2021-05-26 17:41:51 +10:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// The GameObjects in the currently inspected scene.
|
|
|
|
|
/// </summary>
|
2021-07-19 21:43:16 +10:00
|
|
|
|
public static GameObject[] CurrentRootObjects { get; private set; } = new GameObject[0];
|
2021-05-26 17:41:51 +10:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// All currently loaded Scenes.
|
|
|
|
|
/// </summary>
|
2021-07-19 21:43:16 +10:00
|
|
|
|
public static List<Scene> LoadedScenes { get; private set; } = new List<Scene>();
|
2021-05-27 19:30:19 +10:00
|
|
|
|
private static HashSet<Scene> previousLoadedScenes;
|
2021-05-26 17:41:51 +10:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// The names of all scenes in the build settings, if they could be retrieved.
|
|
|
|
|
/// </summary>
|
2021-08-06 18:44:13 +10:00
|
|
|
|
public static readonly List<string> AllSceneNames = new List<string>();
|
2021-05-26 17:41:51 +10:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Whether or not we successfuly retrieved the names of the scenes in the build settings.
|
|
|
|
|
/// </summary>
|
2021-08-06 18:44:13 +10:00
|
|
|
|
public static bool WasAbleToGetScenesInBuild { get; private set; }
|
2021-05-26 17:41:51 +10:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Invoked when the currently inspected Scene changes. The argument is the new scene.
|
|
|
|
|
/// </summary>
|
|
|
|
|
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>
|
2021-07-19 21:43:16 +10:00
|
|
|
|
public static event Action<List<Scene>> OnLoadedScenesChanged;
|
2021-05-26 17:41:51 +10:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
2021-05-29 14:50:27 +10:00
|
|
|
|
/// Equivalent to <see cref="SceneManager.sceneCount"/> + 2, to include 'DontDestroyOnLoad' and the 'None' scene.
|
2021-05-26 17:41:51 +10:00
|
|
|
|
/// </summary>
|
|
|
|
|
public static int LoadedSceneCount => SceneManager.sceneCount + 2;
|
|
|
|
|
|
|
|
|
|
internal static Scene DontDestroyScene => DontDestroyMe.scene;
|
|
|
|
|
internal static int DontDestroyHandle => DontDestroyScene.handle;
|
|
|
|
|
|
|
|
|
|
internal static GameObject DontDestroyMe
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
if (!dontDestroyObject)
|
|
|
|
|
{
|
|
|
|
|
dontDestroyObject = new GameObject("DontDestroyMe");
|
|
|
|
|
GameObject.DontDestroyOnLoad(dontDestroyObject);
|
|
|
|
|
}
|
|
|
|
|
return dontDestroyObject;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
private static GameObject dontDestroyObject;
|
|
|
|
|
|
2021-05-27 19:30:19 +10:00
|
|
|
|
public static bool InspectingAssetScene => SelectedScene.HasValue && SelectedScene.Value == default;
|
2021-05-26 17:41:51 +10:00
|
|
|
|
|
|
|
|
|
internal static void Init()
|
|
|
|
|
{
|
|
|
|
|
// Try to get all scenes in the build settings. This may not work.
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
Type sceneUtil = ReflectionUtility.GetTypeByName("UnityEngine.SceneManagement.SceneUtility");
|
|
|
|
|
if (sceneUtil == null)
|
|
|
|
|
throw new Exception("This version of Unity does not ship with the 'SceneUtility' class, or it was not unstripped.");
|
2021-06-05 19:36:09 +10:00
|
|
|
|
|
2021-05-26 17:41:51 +10:00
|
|
|
|
var method = sceneUtil.GetMethod("GetScenePathByBuildIndex", ReflectionUtility.FLAGS);
|
|
|
|
|
int sceneCount = SceneManager.sceneCountInBuildSettings;
|
|
|
|
|
for (int i = 0; i < sceneCount; i++)
|
|
|
|
|
{
|
|
|
|
|
var scenePath = (string)method.Invoke(null, new object[] { i });
|
2021-08-06 18:44:13 +10:00
|
|
|
|
AllSceneNames.Add(scenePath);
|
2021-05-26 17:41:51 +10:00
|
|
|
|
}
|
2021-10-26 15:12:44 +11:00
|
|
|
|
|
|
|
|
|
WasAbleToGetScenesInBuild = true;
|
2021-05-26 17:41:51 +10:00
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
2021-08-06 18:44:13 +10:00
|
|
|
|
WasAbleToGetScenesInBuild = false;
|
2021-05-26 17:41:51 +10:00
|
|
|
|
ExplorerCore.LogWarning($"Unable to generate list of all Scenes in the build: {ex}");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
internal static void Update()
|
|
|
|
|
{
|
2021-05-27 19:30:19 +10:00
|
|
|
|
// check if the loaded scenes changed. always confirm DontDestroy / HideAndDontSave
|
|
|
|
|
int confirmedCount = 2;
|
|
|
|
|
bool inspectedExists = SelectedScene == DontDestroyScene || (SelectedScene.HasValue && SelectedScene.Value == default);
|
2021-05-26 17:41:51 +10:00
|
|
|
|
|
2021-07-19 21:43:16 +10:00
|
|
|
|
LoadedScenes.Clear();
|
2021-05-26 17:41:51 +10:00
|
|
|
|
|
|
|
|
|
for (int i = 0; i < SceneManager.sceneCount; i++)
|
|
|
|
|
{
|
|
|
|
|
Scene scene = SceneManager.GetSceneAt(i);
|
|
|
|
|
if (scene == default || !scene.isLoaded)
|
|
|
|
|
continue;
|
|
|
|
|
|
2021-05-27 19:30:19 +10:00
|
|
|
|
// If no changes yet, ensure the previous list contained the scene
|
|
|
|
|
if (previousLoadedScenes != null && previousLoadedScenes.Contains(scene))
|
|
|
|
|
confirmedCount++;
|
2021-05-26 17:41:51 +10:00
|
|
|
|
|
|
|
|
|
// If we have not yet confirmed inspectedExists, check if this scene is our currently inspected one.
|
2021-05-27 19:30:19 +10:00
|
|
|
|
if (!inspectedExists && scene == SelectedScene)
|
2021-05-26 17:41:51 +10:00
|
|
|
|
inspectedExists = true;
|
|
|
|
|
|
2021-07-19 21:43:16 +10:00
|
|
|
|
LoadedScenes.Add(scene);
|
2021-05-26 17:41:51 +10:00
|
|
|
|
}
|
|
|
|
|
|
2021-07-19 21:43:16 +10:00
|
|
|
|
LoadedScenes.Add(DontDestroyScene);
|
|
|
|
|
LoadedScenes.Add(default);
|
2021-12-28 23:24:44 +11:00
|
|
|
|
|
|
|
|
|
bool anyChange = confirmedCount != LoadedScenes.Count;
|
|
|
|
|
|
2021-07-19 21:43:16 +10:00
|
|
|
|
previousLoadedScenes = new HashSet<Scene>(LoadedScenes);
|
2021-05-26 17:41:51 +10:00
|
|
|
|
|
|
|
|
|
// Default to first scene if none selected or previous selection no longer exists.
|
|
|
|
|
if (!inspectedExists)
|
2021-07-19 21:43:16 +10:00
|
|
|
|
SelectedScene = LoadedScenes.First();
|
2021-05-26 17:41:51 +10:00
|
|
|
|
|
|
|
|
|
// Notify on the list changing at all
|
|
|
|
|
if (anyChange)
|
|
|
|
|
OnLoadedScenesChanged?.Invoke(LoadedScenes);
|
|
|
|
|
|
|
|
|
|
// Finally, update the root objects list.
|
|
|
|
|
if (SelectedScene != null && ((Scene)SelectedScene).IsValid())
|
2021-07-19 21:43:16 +10:00
|
|
|
|
CurrentRootObjects = RuntimeProvider.Instance.GetRootGameObjects((Scene)SelectedScene);
|
2021-05-26 17:41:51 +10:00
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
var allObjects = RuntimeProvider.Instance.FindObjectsOfTypeAll(typeof(GameObject));
|
2021-05-27 19:30:19 +10:00
|
|
|
|
var objects = new List<GameObject>();
|
2021-05-26 17:41:51 +10:00
|
|
|
|
foreach (var obj in allObjects)
|
|
|
|
|
{
|
|
|
|
|
var go = obj.TryCast<GameObject>();
|
|
|
|
|
if (go.transform.parent == null && !go.scene.IsValid())
|
2021-05-27 19:30:19 +10:00
|
|
|
|
objects.Add(go);
|
2021-05-26 17:41:51 +10:00
|
|
|
|
}
|
2021-07-19 21:43:16 +10:00
|
|
|
|
CurrentRootObjects = objects.ToArray();
|
2021-05-26 17:41:51 +10:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|