Last active
April 28, 2025 22:06
-
-
Save wtrebella/671b4dff339be37cc11bd302461bc159 to your computer and use it in GitHub Desktop.
Scene Hierarchy Window is a Unity window that simplifies and speeds up the management of scenes that are loaded/unloaded/active in the hierarchy
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Created using Unity 2023.2, but if I'm not mistaken, this should work in older versions of Unity too | |
using System.Linq; | |
using UnityEditor; | |
using UnityEditor.SceneManagement; | |
using UnityEngine; | |
using UnityEngine.SceneManagement; | |
namespace Whitakr.Utils.Editor | |
{ | |
public class SceneHierarchyWindow : EditorWindow | |
{ | |
const float LABEL_PADDING = 10f; | |
const float BUTTON_WIDTH = 80f; | |
[MenuItem("Whitakr/Utils/Scene Hierarchy Window")] | |
public static void ShowWindow() | |
{ | |
SceneHierarchyWindow window = GetWindow<SceneHierarchyWindow>(); | |
window.titleContent = new("Scene Hierarchy Window"); | |
window.Show(); | |
} | |
void OnGUI() | |
{ | |
if (Application.isPlaying) | |
{ | |
EditorGUILayout.HelpBox("Scene Hierarchy Window is not available in Play Mode.", MessageType.Info); | |
return; | |
} | |
SceneSetup[] setups = EditorSceneManager.GetSceneManagerSetup(); | |
float previousLabelWidth = EditorGUIUtility.labelWidth; | |
float minLabelWidth = setups | |
.Select(setup => System.IO.Path.GetFileNameWithoutExtension(setup.path)) | |
.Select(sceneName => GUI.skin.label.CalcSize(new(sceneName)).x) | |
.Max(); | |
EditorGUIUtility.labelWidth = minLabelWidth + LABEL_PADDING; | |
foreach (SceneSetup setup in setups) | |
{ | |
string scenePath = setup.path; | |
string sceneName = System.IO.Path.GetFileNameWithoutExtension(scenePath); | |
EditorGUILayout.BeginHorizontal(); | |
EditorGUILayout.PrefixLabel(sceneName); | |
if (setup.isActive) | |
{ | |
EditorGUILayout.LabelField("Active", EditorStyles.boldLabel); | |
} | |
else | |
{ | |
if (setup.isLoaded) | |
{ | |
if (GUILayout.Button("Unload", GUILayout.Width(BUTTON_WIDTH))) | |
{ | |
Unload(scenePath); | |
} | |
} | |
else | |
{ | |
if (GUILayout.Button("Load", GUILayout.Width(BUTTON_WIDTH))) | |
{ | |
Load(scenePath); | |
} | |
} | |
if (GUILayout.Button("Set Active", GUILayout.Width(BUTTON_WIDTH))) | |
{ | |
SetActive(scenePath); | |
} | |
} | |
EditorGUILayout.EndHorizontal(); | |
} | |
if (setups.Any(s => !s.isLoaded)) | |
{ | |
if (GUILayout.Button("Load All")) | |
{ | |
foreach (SceneSetup setup in setups) | |
{ | |
if (!setup.isLoaded) | |
{ | |
Load(setup.path); | |
} | |
} | |
} | |
} | |
else if (setups.Length > 1) // Only show unload all if there are multiple scenes loaded, since Active scene can't be unloaded | |
{ | |
if (GUILayout.Button("Unload All")) | |
{ | |
foreach (SceneSetup setup in setups) | |
{ | |
if (setup.isLoaded && !setup.isActive) | |
{ | |
Unload(setup.path); | |
} | |
} | |
} | |
} | |
EditorGUIUtility.labelWidth = previousLabelWidth; | |
} | |
static void Load(string scenePath) | |
{ | |
EditorSceneManager.OpenScene(scenePath, OpenSceneMode.Additive); | |
} | |
static void Unload(string scenePath) | |
{ | |
EditorSceneManager.CloseScene(SceneManager.GetSceneByPath(scenePath), false); | |
} | |
static void SetActive(string scenePath) | |
{ | |
Scene scene = SceneManager.GetSceneByPath(scenePath); | |
if (!scene.isLoaded) | |
{ | |
EditorSceneManager.OpenScene(scenePath, OpenSceneMode.Additive); | |
} | |
SceneManager.SetActiveScene(scene); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment