module-navigation-tool/Editor/Toolbar/Tools/ToolScenePicker.cs

158 lines
5.2 KiB
C#

using System;
using System.Collections.Generic;
using System.IO;
using JetBrains.Annotations;
using UnityEditor;
using UnityEditor.SceneManagement;
using UnityEngine;
using UnityEngine.SceneManagement;
namespace Module.NavigationTool.Editor.Toolbar
{
[UsedImplicitly]
internal sealed class ToolScenePicker : AbstractToolbarDrawer
{
public override bool Visible => ToolbarScenePickerSettings.IsSceneEnabled;
public override bool Enabled => !EditorApplication.isPlaying && !EditorApplication.isPlayingOrWillChangePlaymode;
public override EToolbarPlacement Placement => EToolbarPlacement.Right;
public override int Priority => (int)EToolbarPriority.Medium;
private static bool IS_DIRTY = true;
private static int SELECTED_INDEX = -1;
private static string[] OPTIONS = new string[0];
private static string[] PATHS = new string[0];
private static void Initialize()
{
if (!IS_DIRTY)
return;
var listNames = new List<string>();
var listPaths = new List<string>();
InitializeBuildSettingsScenes(listNames, listPaths);
InitializeRemainingScenes(listNames, listPaths);
OPTIONS = listNames.ToArray();
PATHS = listPaths.ToArray();
Scene activeScene = SceneManager.GetActiveScene();
SELECTED_INDEX = listPaths.IndexOf(activeScene.path);
IS_DIRTY = false;
}
private static void InitializeBuildSettingsScenes(List<string> listNames, List<string> listPaths)
{
EditorBuildSettingsScene[] scenes = EditorBuildSettings.scenes;
for (var i = 0; i < scenes.Length; i++)
{
if (string.IsNullOrEmpty(scenes[i].path))
continue;
listNames.Add($"{Path.GetFileNameWithoutExtension(scenes[i].path)}");
listPaths.Add(scenes[i].path);
}
}
private static void InitializeRemainingScenes(List<string> listNames, List<string> listPaths)
{
List<string> sortByAssetLabels = ToolbarScenePickerSettings.SceneAssetLabels;
var assetLabelToScenes = new SceneSortElement[sortByAssetLabels.Count + 1];
string[] guids = AssetDatabase.FindAssets("t:scene");
for (var i = 0; i < guids.Length; i++)
{
string path = AssetDatabase.GUIDToAssetPath(guids[i]);
if (listPaths.Contains(path) || !path.StartsWith("Assets"))
continue;
var scene = AssetDatabase.LoadAssetAtPath<SceneAsset>(path);
if (scene == null)
continue;
string sceneName = path.Substring(7, path.Length - 13)
.Replace('/', '\\');
string[] assetLabels = AssetDatabase.GetLabels(scene);
int index = -1;
for (var j = 0; j < assetLabels.Length; j++)
{
index = sortByAssetLabels.IndexOf(assetLabels[j]);
if (index != -1)
break;
}
if (index == -1)
index = sortByAssetLabels.Count;
if (assetLabelToScenes[index] == null)
assetLabelToScenes[index] = new SceneSortElement();
assetLabelToScenes[index].names.Add(sceneName);
assetLabelToScenes[index].paths.Add(path);
}
for (var i = 0; i < assetLabelToScenes.Length; i++)
{
SceneSortElement e = assetLabelToScenes[i];
if (e == null)
continue;
listNames.Add(string.Empty);
listPaths.Add(string.Empty);
listNames.AddRange(e.names);
listPaths.AddRange(e.paths);
}
}
public override void Update()
{
Initialize();
}
protected override void Draw(Rect rect)
{
Initialize();
int temp = EditorGUI.Popup(rect, SELECTED_INDEX, OPTIONS, styles.popup);
if (temp <= -1 || temp == SELECTED_INDEX || OPTIONS.Length == 0)
return;
if (string.IsNullOrEmpty(PATHS[temp]))
return;
try
{
Scene scene = EditorSceneManager.OpenScene(PATHS[temp], OpenSceneMode.Single);
if (scene.isLoaded)
SELECTED_INDEX = temp;
}
catch (Exception e)
{
Debug.LogWarningFormat("Failed to load scene ({0}), due to exception: {1}", PATHS[temp], e.Message);
}
}
public override float CalculateWidth()
{
return 100.0f;
}
public static void SetAsDirty()
{
IS_DIRTY = true;
}
private sealed class SceneSortElement
{
public readonly List<string> names = new List<string>();
public readonly List<string> paths = new List<string>();
}
}
}