Files
AppleHillsProduction/Assets/Editor/Tools/SceneBrowserWindow.cs
2025-10-27 15:21:23 +01:00

133 lines
4.3 KiB
C#

using UnityEditor;
using UnityEditor.SceneManagement;
using UnityEngine;
using System.Collections.Generic;
using System.IO;
using System.Linq;
public class SceneBrowserWindow : EditorWindow
{
private class SceneInfo
{
public string path;
public string name;
public string folder;
public bool inBuildSettings;
}
private Vector2 _scroll;
private List<SceneInfo> _scenes = new List<SceneInfo>();
private Dictionary<string, List<SceneInfo>> _scenesByFolder = new Dictionary<string, List<SceneInfo>>();
[MenuItem("Tools/Scene Browser")]
public static void ShowWindow()
{
var window = GetWindow<SceneBrowserWindow>(false, "Scene Browser", true);
window.RefreshScenes();
}
private void OnFocus()
{
RefreshScenes();
}
private void RefreshScenes()
{
_scenes.Clear();
_scenesByFolder.Clear();
string[] guids = AssetDatabase.FindAssets("t:Scene", new[] { "Assets/Scenes" });
var buildScenes = EditorBuildSettings.scenes.Select(s => s.path).ToHashSet();
foreach (var guid in guids)
{
string path = AssetDatabase.GUIDToAssetPath(guid);
string name = Path.GetFileNameWithoutExtension(path);
string folder = Path.GetDirectoryName(path).Replace("\\", "/");
if (folder == "Assets/Scenes") folder = "";
var info = new SceneInfo
{
path = path,
name = name,
folder = folder,
inBuildSettings = buildScenes.Contains(path)
};
_scenes.Add(info);
if (!_scenesByFolder.ContainsKey(folder))
_scenesByFolder[folder] = new List<SceneInfo>();
_scenesByFolder[folder].Add(info);
}
}
private void OnGUI()
{
if (GUILayout.Button("Refresh"))
RefreshScenes();
_scroll = EditorGUILayout.BeginScrollView(_scroll);
// Create a safe copy to avoid collection modification during enumeration
var foldersCopy = _scenesByFolder.Keys.ToList();
// Top-level scenes
if (foldersCopy.Contains("") && _scenesByFolder.ContainsKey(""))
{
var topLevelScenes = _scenesByFolder[""].ToList();
foreach (var scene in topLevelScenes)
DrawSceneRow(scene);
EditorGUILayout.Space();
}
// Subfolders
foreach (var folderKey in foldersCopy)
{
if (string.IsNullOrEmpty(folderKey)) continue;
if (!_scenesByFolder.ContainsKey(folderKey)) continue;
EditorGUILayout.LabelField(folderKey, EditorStyles.boldLabel);
var scenesInFolder = _scenesByFolder[folderKey].ToList();
foreach (var scene in scenesInFolder)
DrawSceneRow(scene);
EditorGUILayout.Space();
}
EditorGUILayout.EndScrollView();
}
private void DrawSceneRow(SceneInfo scene)
{
EditorGUILayout.BeginHorizontal();
EditorGUILayout.LabelField(scene.name, GUILayout.Width(180));
if (GUILayout.Button("Open", GUILayout.Width(50)))
{
if (EditorSceneManager.SaveCurrentModifiedScenesIfUserWantsTo())
EditorSceneManager.OpenScene(scene.path);
}
if (GUILayout.Button("Locate", GUILayout.Width(50)))
{
var obj = AssetDatabase.LoadAssetAtPath<SceneAsset>(scene.path);
EditorGUIUtility.PingObject(obj);
}
bool inBuild = scene.inBuildSettings;
bool newInBuild = GUILayout.Toggle(inBuild, "In Build", GUILayout.Width(70));
if (newInBuild != inBuild)
{
ToggleSceneInBuildSettings(scene.path, newInBuild);
scene.inBuildSettings = newInBuild;
}
EditorGUILayout.EndHorizontal();
}
private void ToggleSceneInBuildSettings(string path, bool add)
{
var scenes = EditorBuildSettings.scenes.ToList();
if (add)
{
if (!scenes.Any(s => s.path == path))
scenes.Add(new EditorBuildSettingsScene(path, true));
}
else
{
scenes = scenes.Where(s => s.path != path).ToList();
}
EditorBuildSettings.scenes = scenes.ToArray();
}
}