Scene picker: Added option to add groups of scenes to open
This commit is contained in:
parent
41604b98e7
commit
a86f76904e
28 changed files with 1052 additions and 225 deletions
3
Editor/Toolbar/Tools/ScenePickerObjects.meta
Normal file
3
Editor/Toolbar/Tools/ScenePickerObjects.meta
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: cf9c741582d646d5ab02533554680715
|
||||
timeCreated: 1693390703
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
namespace Module.NavigationTool.Editor.Toolbar
|
||||
{
|
||||
public enum ESceneGroupFilterType
|
||||
{
|
||||
AssetLabels,
|
||||
NameContains,
|
||||
PathContains
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 6cf395ccc24c46b18597cfbf6d4e32fd
|
||||
timeCreated: 1693390754
|
||||
14
Editor/Toolbar/Tools/ScenePickerObjects/SceneGroup.cs
Normal file
14
Editor/Toolbar/Tools/ScenePickerObjects/SceneGroup.cs
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Module.NavigationTool.Editor.Toolbar
|
||||
{
|
||||
[Serializable]
|
||||
public sealed class SceneGroup
|
||||
{
|
||||
public string name;
|
||||
public ESceneGroupFilterType filterType;
|
||||
public string optionalMainScenePath;
|
||||
public List<string> filters = new();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 4b0f8e524da24c2e8d0d6c3d0a446059
|
||||
timeCreated: 1693390715
|
||||
14
Editor/Toolbar/Tools/ScenePickerObjects/SceneGroupArray.cs
Normal file
14
Editor/Toolbar/Tools/ScenePickerObjects/SceneGroupArray.cs
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Module.NavigationTool.Editor.Toolbar
|
||||
{
|
||||
[Serializable]
|
||||
public sealed class SceneGroupArray
|
||||
{
|
||||
public List<SceneGroup> groups = new();
|
||||
|
||||
public int Count => groups.Count;
|
||||
public SceneGroup this[int index] => groups[index];
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 59bece5e9d5f4b539434937529afb0e7
|
||||
timeCreated: 1693390710
|
||||
389
Editor/Toolbar/Tools/ScenePickerObjects/ScenePickerList.cs
Normal file
389
Editor/Toolbar/Tools/ScenePickerObjects/ScenePickerList.cs
Normal file
|
|
@ -0,0 +1,389 @@
|
|||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEngine.SceneManagement;
|
||||
|
||||
namespace Module.NavigationTool.Editor.Toolbar
|
||||
{
|
||||
internal sealed class ScenePickerList
|
||||
{
|
||||
public GUIContent[] labels = new GUIContent[0];
|
||||
public readonly List<SceneElement> scenes = new List<SceneElement>();
|
||||
public readonly List<int> selected = new List<int>();
|
||||
|
||||
public void Refresh()
|
||||
{
|
||||
scenes.Clear();
|
||||
selected.Clear();
|
||||
|
||||
var projectSettings = new ToolbarProjectSettings();
|
||||
projectSettings.Load();
|
||||
var settings = projectSettings.GetValueAs<ToolbarScenePickerProjectSettings.Settings>();
|
||||
|
||||
List<WorkingSetScene> assets = GetWorkingSet();
|
||||
FetchAllScenesFromBuildSettings(assets);
|
||||
FetchAllScenesFromLabels(assets, settings.labels);
|
||||
FetchAllScenesFromSceneGroups(assets, settings.sceneGroups);
|
||||
FetchAllRemainingScenes(assets);
|
||||
|
||||
FetchAllLabels();
|
||||
FetchAllSelectedIndices();
|
||||
}
|
||||
|
||||
private void FetchAllScenesFromBuildSettings(List<WorkingSetScene> assets)
|
||||
{
|
||||
for (var i = 0; i < assets.Count; i++)
|
||||
{
|
||||
WorkingSetScene asset = assets[i];
|
||||
|
||||
if (!asset.inBuildSettings)
|
||||
continue;
|
||||
|
||||
scenes.Add(new SceneElement
|
||||
{
|
||||
name = asset.name,
|
||||
shortname = asset.shortname,
|
||||
paths = { asset.path }
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void FetchAllScenesFromLabels(List<WorkingSetScene> assets, List<string> labels)
|
||||
{
|
||||
List<WorkingSetScene> filteredScenes = GetAllWorkingSetScenesWithLabels(assets, labels);
|
||||
filteredScenes = FilterToUniques(filteredScenes);
|
||||
filteredScenes = FilterAllExcept(filteredScenes, scenes);
|
||||
|
||||
if (filteredScenes.Count != 0)
|
||||
scenes.Add(new SceneElement{ includeAsSelectable = false });
|
||||
|
||||
for (var i = 0; i < filteredScenes.Count; i++)
|
||||
{
|
||||
scenes.Add(new SceneElement
|
||||
{
|
||||
name = filteredScenes[i].name,
|
||||
shortname = filteredScenes[i].shortname,
|
||||
paths = { filteredScenes[i].path }
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void FetchAllScenesFromSceneGroups(List<WorkingSetScene> assets, SceneGroupArray sceneGroups)
|
||||
{
|
||||
if (sceneGroups.Count != 0)
|
||||
scenes.Add(new SceneElement{ includeAsSelectable = false });
|
||||
|
||||
for (var i = 0; i < sceneGroups.Count; i++)
|
||||
{
|
||||
SceneGroup sceneGroup = sceneGroups[i];
|
||||
string name = sceneGroup.name;
|
||||
List<WorkingSetScene> filteredScenes;
|
||||
|
||||
if (sceneGroup.filterType == ESceneGroupFilterType.AssetLabels)
|
||||
{
|
||||
filteredScenes = GetAllWorkingSetScenesWithLabels(assets, sceneGroup.filters);
|
||||
}
|
||||
else if (sceneGroup.filterType == ESceneGroupFilterType.NameContains)
|
||||
{
|
||||
filteredScenes = GetAllWorkingSetScenesWithNameContaining(assets, sceneGroup.filters);
|
||||
}
|
||||
else
|
||||
{
|
||||
filteredScenes = GetAllWorkingSetScenesWithPathContaining(assets, sceneGroup.filters);
|
||||
name = sceneGroup.name.Replace("/", "\\");
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(sceneGroup.optionalMainScenePath))
|
||||
SetWorkingSceneAsFirst(filteredScenes, sceneGroup.optionalMainScenePath);
|
||||
|
||||
filteredScenes = FilterToUniques(filteredScenes);
|
||||
|
||||
var scene = new SceneElement
|
||||
{
|
||||
name = name,
|
||||
shortname = name,
|
||||
isGroup = true
|
||||
};
|
||||
|
||||
for (var j = 0; j < filteredScenes.Count; j++)
|
||||
{
|
||||
scene.paths.Add(filteredScenes[j].path);
|
||||
}
|
||||
|
||||
scene.name += $" ({scene.paths.Count})";
|
||||
scenes.Add(scene);
|
||||
}
|
||||
}
|
||||
|
||||
private void FetchAllRemainingScenes(List<WorkingSetScene> assets)
|
||||
{
|
||||
List<WorkingSetScene> filteredScenes = FilterAllExcept(assets, scenes);
|
||||
|
||||
if (filteredScenes.Count != 0)
|
||||
scenes.Add(new SceneElement{ includeAsSelectable = false });
|
||||
|
||||
for (var i = 0; i < filteredScenes.Count; i++)
|
||||
{
|
||||
scenes.Add(new SceneElement
|
||||
{
|
||||
name = filteredScenes[i].name,
|
||||
shortname = filteredScenes[i].shortname,
|
||||
paths = { filteredScenes[i].path }
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private static List<WorkingSetScene> FilterToUniques(List<WorkingSetScene> list)
|
||||
{
|
||||
var uniques = new List<WorkingSetScene>(list.Count);
|
||||
|
||||
for (var i = 0; i < list.Count; i++)
|
||||
{
|
||||
if (!uniques.Contains(list[i]))
|
||||
uniques.Add(list[i]);
|
||||
}
|
||||
|
||||
return uniques;
|
||||
}
|
||||
|
||||
private static List<WorkingSetScene> FilterAllExcept(List<WorkingSetScene> list, List<SceneElement> except, bool includeGroups = false)
|
||||
{
|
||||
var filtered = new List<WorkingSetScene>(list.Count);
|
||||
|
||||
for (var i = 0; i < list.Count; i++)
|
||||
{
|
||||
var contains = false;
|
||||
|
||||
for (var j = 0; j < except.Count; j++)
|
||||
{
|
||||
if (except[j].isGroup && !includeGroups)
|
||||
continue;
|
||||
if (!except[j].paths.Contains(list[i].path))
|
||||
continue;
|
||||
|
||||
contains = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!contains)
|
||||
filtered.Add(list[i]);
|
||||
}
|
||||
|
||||
return filtered;
|
||||
}
|
||||
|
||||
private void FetchAllLabels()
|
||||
{
|
||||
labels = new GUIContent[scenes.Count];
|
||||
|
||||
for (var i = 0; i < scenes.Count; i++)
|
||||
{
|
||||
labels[i] = new GUIContent(scenes[i].name);
|
||||
}
|
||||
}
|
||||
|
||||
private void FetchAllSelectedIndices()
|
||||
{
|
||||
for (var i = 0; i < SceneManager.sceneCount; i++)
|
||||
{
|
||||
Scene scene = SceneManager.GetSceneAt(i);
|
||||
|
||||
if (string.IsNullOrEmpty(scene.path))
|
||||
continue;
|
||||
|
||||
int index = IndexOfPath(scenes, scene.path, false);
|
||||
|
||||
if (index != -1)
|
||||
selected.Add(index);
|
||||
}
|
||||
}
|
||||
|
||||
private static List<WorkingSetScene> GetAllWorkingSetScenesWithLabels(List<WorkingSetScene> assets, List<string> labels)
|
||||
{
|
||||
var list = new List<WorkingSetScene>();
|
||||
|
||||
for (var i = 0; i < labels.Count; i++)
|
||||
{
|
||||
list.AddRange(GetAllWorkingSetScenesWithLabel(assets, labels[i]));
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
private static List<WorkingSetScene> GetAllWorkingSetScenesWithLabel(List<WorkingSetScene> assets, string label)
|
||||
{
|
||||
var list = new List<WorkingSetScene>();
|
||||
|
||||
for (var i = 0; i < assets.Count; i++)
|
||||
{
|
||||
if (assets[i].labels.Contains(label))
|
||||
list.Add(assets[i]);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
private static List<WorkingSetScene> GetAllWorkingSetScenesWithNameContaining(List<WorkingSetScene> assets, List<string> filters)
|
||||
{
|
||||
var list = new List<WorkingSetScene>();
|
||||
|
||||
for (var i = 0; i < assets.Count; i++)
|
||||
{
|
||||
for (var j = 0; j < filters.Count; j++)
|
||||
{
|
||||
if (!assets[i].shortname.Contains(filters[j]))
|
||||
continue;
|
||||
|
||||
list.Add(assets[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
private static List<WorkingSetScene> GetAllWorkingSetScenesWithPathContaining(List<WorkingSetScene> assets, List<string> filters)
|
||||
{
|
||||
var list = new List<WorkingSetScene>();
|
||||
|
||||
for (var i = 0; i < assets.Count; i++)
|
||||
{
|
||||
for (var j = 0; j < filters.Count; j++)
|
||||
{
|
||||
if (!PathContains(assets[i].path, filters[j]))
|
||||
continue;
|
||||
|
||||
list.Add(assets[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
private static bool IsValidScene(string path)
|
||||
{
|
||||
if (string.IsNullOrEmpty(path))
|
||||
return false;
|
||||
if (!path.StartsWith("Assets"))
|
||||
return false;
|
||||
|
||||
return AssetDatabase.LoadAssetAtPath<SceneAsset>(path) != null;
|
||||
}
|
||||
|
||||
public int IndexOfPath(string path, bool includeGroups)
|
||||
{
|
||||
return IndexOfPath(scenes, path, includeGroups);
|
||||
}
|
||||
|
||||
private static int IndexOfPath(List<SceneElement> list, string path, bool includeGroups)
|
||||
{
|
||||
for (var i = 0; i < list.Count; i++)
|
||||
{
|
||||
if (!includeGroups && list[i].isGroup)
|
||||
continue;
|
||||
if (!list[i].includeAsSelectable)
|
||||
continue;
|
||||
|
||||
if (list[i].paths.IndexOf(path) != -1)
|
||||
return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
private static bool PathContains(string path, string subpath)
|
||||
{
|
||||
path = path.Replace("\\", "/");
|
||||
subpath = subpath.Replace("\\", "/");
|
||||
return path.Contains(subpath);
|
||||
}
|
||||
|
||||
private static bool PathEquals(string path, string subpath)
|
||||
{
|
||||
path = path.Replace("\\", "/");
|
||||
subpath = subpath.Replace("\\", "/");
|
||||
return path.Equals(subpath);
|
||||
}
|
||||
|
||||
private static void SetWorkingSceneAsFirst(List<WorkingSetScene> scenes, string path)
|
||||
{
|
||||
int index = -1;
|
||||
|
||||
for (var i = 0; i < scenes.Count; i++)
|
||||
{
|
||||
if (!PathEquals(scenes[i].path, path))
|
||||
continue;
|
||||
|
||||
index = i;
|
||||
break;
|
||||
}
|
||||
|
||||
if (index == -1)
|
||||
return;
|
||||
|
||||
WorkingSetScene temp = scenes[0];
|
||||
scenes[0] = scenes[index];
|
||||
scenes[index] = temp;
|
||||
}
|
||||
|
||||
private static List<WorkingSetScene> GetWorkingSet()
|
||||
{
|
||||
var workingSet = new List<WorkingSetScene>();
|
||||
string[] guids = AssetDatabase.FindAssets("t:scene");
|
||||
EditorBuildSettingsScene[] buildSettingsScenes = EditorBuildSettings.scenes;
|
||||
|
||||
for (var i = 0; i < guids.Length; i++)
|
||||
{
|
||||
string path = AssetDatabase.GUIDToAssetPath(guids[i]);
|
||||
|
||||
if (!IsValidScene(path))
|
||||
continue;
|
||||
|
||||
var asset = AssetDatabase.LoadAssetAtPath<SceneAsset>(path);
|
||||
string sceneName = path.Substring(7, path.Length - 13).Replace('/', '\\');
|
||||
var inBuildSettings = false;
|
||||
|
||||
for (var j = 0; j < buildSettingsScenes.Length; j++)
|
||||
{
|
||||
if (!buildSettingsScenes[j].path.Equals(path))
|
||||
continue;
|
||||
|
||||
inBuildSettings = true;
|
||||
break;
|
||||
}
|
||||
|
||||
workingSet.Add(new WorkingSetScene
|
||||
{
|
||||
path = path,
|
||||
name = sceneName,
|
||||
shortname = Path.GetFileNameWithoutExtension(path),
|
||||
labels = AssetDatabase.GetLabels(asset),
|
||||
inBuildSettings = inBuildSettings
|
||||
});
|
||||
}
|
||||
|
||||
return workingSet;
|
||||
}
|
||||
|
||||
public sealed class SceneElement
|
||||
{
|
||||
public string name;
|
||||
public string shortname;
|
||||
public bool includeAsSelectable = true;
|
||||
public bool isGroup;
|
||||
public readonly List<string> paths = new List<string>();
|
||||
}
|
||||
|
||||
private sealed class WorkingSetScene
|
||||
{
|
||||
public string path;
|
||||
public string name;
|
||||
public string shortname;
|
||||
public string[] labels;
|
||||
public bool inBuildSettings;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: d336bd910c0049c8ab47f94d9924baf3
|
||||
timeCreated: 1693405779
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Module.NavigationTool.Editor.Toolbar
|
||||
{
|
||||
internal sealed class ToolbarScenePickerProjectSettings : IToolbarProjectSettings
|
||||
{
|
||||
public string Title => "Scene";
|
||||
public bool IsSettingsDirty { get; private set; }
|
||||
|
||||
private StringReordableListDrawer assetLabelList;
|
||||
private SceneGroupReordableListDrawer sceneGroupList;
|
||||
|
||||
private ToolbarProjectSettings projectSettings;
|
||||
private Settings settings;
|
||||
|
||||
public void Initialize(ToolbarProjectSettings projectSettings)
|
||||
{
|
||||
this.projectSettings = projectSettings;
|
||||
settings = projectSettings.GetValueAs<Settings>();
|
||||
|
||||
assetLabelList = new StringReordableListDrawer(settings.labels, "Scene sorting by Asset label");
|
||||
assetLabelList.onChanged += ToolScenePicker.SetAsDirty;
|
||||
|
||||
sceneGroupList = new SceneGroupReordableListDrawer(settings.sceneGroups.groups, "Scene groups");
|
||||
sceneGroupList.onChanged += ToolScenePicker.SetAsDirty;
|
||||
}
|
||||
|
||||
public void Draw()
|
||||
{
|
||||
assetLabelList.DoLayoutList();
|
||||
sceneGroupList.DoLayoutList();
|
||||
IsSettingsDirty = assetLabelList.IsDirty || sceneGroupList.IsDirty;
|
||||
}
|
||||
|
||||
public void SetSettingsValue()
|
||||
{
|
||||
projectSettings.SetValue(settings);
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public sealed class Settings
|
||||
{
|
||||
public List<string> labels = new();
|
||||
public SceneGroupArray sceneGroups = new();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 3dd46bde8e5b4cca9c95d051862f5817
|
||||
timeCreated: 1693466453
|
||||
|
|
@ -1,9 +1,4 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEditor;
|
||||
using UnityEditorInternal;
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
|
||||
namespace Module.NavigationTool.Editor.Toolbar
|
||||
{
|
||||
|
|
@ -12,7 +7,6 @@ namespace Module.NavigationTool.Editor.Toolbar
|
|||
public string Title => "Scene";
|
||||
|
||||
private const string PREF_IS_SCENE_ENABLED = "ToolbarSettings_IsSceneEnabled";
|
||||
private const string PREF_SCENE_ASSET_LABELS = "ToolbarSettings_SceneAssetLabels";
|
||||
private const string PREF_SCENE_PICKER_LOAD_SET_AS_ADDITIVE_KEY = "ToolbarSettings_ScenePickerLoadSetAsAdditive";
|
||||
|
||||
public static bool IsSceneEnabled
|
||||
|
|
@ -21,78 +15,19 @@ namespace Module.NavigationTool.Editor.Toolbar
|
|||
private set => EditorPrefs.SetBool(PREF_IS_SCENE_ENABLED, value);
|
||||
}
|
||||
|
||||
public static List<string> SceneAssetLabels
|
||||
{
|
||||
get => EditorPrefs.GetString(PREF_SCENE_ASSET_LABELS).Split(',').ToList();
|
||||
private set => EditorPrefs.SetString(PREF_SCENE_ASSET_LABELS, string.Join(",", value));
|
||||
}
|
||||
|
||||
public static bool IsScenePickerSetAsAdditive
|
||||
{
|
||||
get => EditorPrefs.GetBool(PREF_SCENE_PICKER_LOAD_SET_AS_ADDITIVE_KEY, false);
|
||||
set => EditorPrefs.SetBool(PREF_SCENE_PICKER_LOAD_SET_AS_ADDITIVE_KEY, value);
|
||||
}
|
||||
|
||||
private ReorderableList assetLabelList;
|
||||
private List<string> assetLabels;
|
||||
|
||||
public void Initialize()
|
||||
{
|
||||
assetLabels = SceneAssetLabels.ToList();
|
||||
assetLabelList = new ReorderableList(assetLabels, typeof(string), true, true, true, true);
|
||||
assetLabelList.drawElementCallback += OnAssetLabelListDrawElement;
|
||||
assetLabelList.drawHeaderCallback += OnAssetLabelListDrawHeader;
|
||||
assetLabelList.onAddCallback += OnAssetLabelListAddedElement;
|
||||
assetLabelList.onRemoveCallback += OnAssetLabelListRemovedElement;
|
||||
assetLabelList.onReorderCallback += OnAssetLabelListReorder;
|
||||
}
|
||||
|
||||
public void Draw()
|
||||
{
|
||||
IsSceneEnabled = EditorGUILayout.Toggle("Enable Scene picker", IsSceneEnabled);
|
||||
|
||||
if (assetLabelList == null)
|
||||
return;
|
||||
|
||||
assetLabelList.DoLayoutList();
|
||||
SceneAssetLabels = assetLabels;
|
||||
}
|
||||
|
||||
private static void OnAssetLabelListDrawHeader(Rect rect)
|
||||
{
|
||||
EditorGUI.LabelField(rect, "Scene sorting by Asset label");
|
||||
}
|
||||
|
||||
private void OnAssetLabelListDrawElement(Rect rect, int index, bool isActive, bool isFocused)
|
||||
{
|
||||
rect.height -= 2;
|
||||
rect.y += 1;
|
||||
|
||||
string text = assetLabels[index];
|
||||
string temp = EditorGUI.TextField(rect, text);
|
||||
|
||||
if (string.Equals(text, temp, StringComparison.Ordinal))
|
||||
return;
|
||||
|
||||
assetLabels[index] = temp;
|
||||
ToolScenePicker.SetAsDirty();
|
||||
}
|
||||
|
||||
private void OnAssetLabelListAddedElement(ReorderableList list)
|
||||
{
|
||||
assetLabels.Add(string.Empty);
|
||||
ToolScenePicker.SetAsDirty();
|
||||
}
|
||||
|
||||
private void OnAssetLabelListRemovedElement(ReorderableList list)
|
||||
{
|
||||
assetLabels.RemoveAt(list.index);
|
||||
ToolScenePicker.SetAsDirty();
|
||||
}
|
||||
|
||||
private void OnAssetLabelListReorder(ReorderableList list)
|
||||
{
|
||||
ToolScenePicker.SetAsDirty();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,7 +1,4 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text;
|
||||
using JetBrains.Annotations;
|
||||
using UnityEditor;
|
||||
|
|
@ -18,134 +15,22 @@ namespace Module.NavigationTool.Editor.Toolbar
|
|||
public override bool Enabled => !EditorApplication.isPlaying && !EditorApplication.isPlayingOrWillChangePlaymode;
|
||||
public override EToolbarPlacement Placement => EToolbarPlacement.Right;
|
||||
public override int Priority => (int)EToolbarPriority.Medium;
|
||||
|
||||
private static readonly List<int> SELECTED_INDICES = new List<int>();
|
||||
private static readonly StringBuilder STRING_BUILDER = new StringBuilder();
|
||||
private static string SCENE_LABEL = string.Empty;
|
||||
private static string[] SCENE_NAMES = new string[0];
|
||||
private static string[] SCENE_SHORT_NAMES = new string[0];
|
||||
private static string[] SCENE_PATHS = new string[0];
|
||||
private static readonly GUIContent LABEL_SCENE_ADDITIVE = new GUIContent(string.Empty, "Additive scene loading (toogle to Single)");
|
||||
private static readonly GUIContent LABEL_SCENE_SINGLE = new GUIContent(string.Empty, "Single scene loading (toggle to Additive)");
|
||||
private static readonly GUIContent LABEL_SCENE_CREATE = new GUIContent(string.Empty, "Create a new scene");
|
||||
private const float BUTTON_WIDTH = 24.0f;
|
||||
|
||||
private static readonly StringBuilder STRING_BUILDER = new StringBuilder();
|
||||
private static readonly ScenePickerList SCENE_LIST = new ScenePickerList();
|
||||
private static string SCENE_LABEL = string.Empty;
|
||||
private static bool IS_DIRTY = true;
|
||||
|
||||
|
||||
private static void Initialize()
|
||||
{
|
||||
if (!IS_DIRTY)
|
||||
return;
|
||||
|
||||
SELECTED_INDICES.Clear();
|
||||
var listNames = new List<string>();
|
||||
var listShortNames = new List<string>();
|
||||
var listPaths = new List<string>();
|
||||
|
||||
InitializeBuildSettingsScenes(listNames, listShortNames, listPaths);
|
||||
InitializeRemainingScenes(listNames, listShortNames, listPaths);
|
||||
|
||||
for (var i = 0; i < SceneManager.sceneCount; i++)
|
||||
{
|
||||
Scene scene = SceneManager.GetSceneAt(i);
|
||||
|
||||
if (string.IsNullOrEmpty(scene.path))
|
||||
continue;
|
||||
|
||||
int index = listPaths.IndexOf(scene.path);
|
||||
|
||||
if (index != -1)
|
||||
SELECTED_INDICES.Add(index);
|
||||
}
|
||||
|
||||
SCENE_NAMES = listNames.ToArray();
|
||||
SCENE_SHORT_NAMES = listShortNames.ToArray();
|
||||
SCENE_PATHS = listPaths.ToArray();
|
||||
SCENE_LIST.Refresh();
|
||||
RefreshSceneLabel();
|
||||
IS_DIRTY = false;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private static void InitializeBuildSettingsScenes(List<string> listNames, List<string> listShortNames, List<string> listPaths)
|
||||
{
|
||||
EditorBuildSettingsScene[] scenes = EditorBuildSettings.scenes;
|
||||
|
||||
for (int i = 0, added = 0; i < scenes.Length; i++)
|
||||
{
|
||||
string path = scenes[i].path;
|
||||
|
||||
if (string.IsNullOrEmpty(path))
|
||||
continue;
|
||||
if (AssetDatabase.LoadAssetAtPath<SceneAsset>(path) == null)
|
||||
continue;
|
||||
|
||||
listNames.Add(Path.GetFileNameWithoutExtension(path));
|
||||
listShortNames.Add(listNames[added]);
|
||||
listPaths.Add(path);
|
||||
added++;
|
||||
}
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private static void InitializeRemainingScenes(List<string> listNames, List<string> listShortNames, 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].shortNames.Add(Path.GetFileName(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);
|
||||
listShortNames.Add(string.Empty);
|
||||
listPaths.Add(string.Empty);
|
||||
|
||||
listNames.AddRange(e.names);
|
||||
listShortNames.AddRange(e.shortNames);
|
||||
listPaths.AddRange(e.paths);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Update()
|
||||
{
|
||||
Initialize();
|
||||
|
|
@ -155,9 +40,9 @@ namespace Module.NavigationTool.Editor.Toolbar
|
|||
{
|
||||
Initialize();
|
||||
|
||||
var rect0 = new Rect(rect.x, rect.y, rect.width - BUTTON_WIDTH * 2.0f, rect.height);
|
||||
var rect1 = new Rect(rect0.xMax, rect.y, BUTTON_WIDTH, rect.height);
|
||||
var rect2 = new Rect(rect1.xMax, rect.y, BUTTON_WIDTH, rect.height);
|
||||
var rect0 = new Rect(rect.x, rect.y, rect.width - Styles.BUTTON_WIDTH * 2.0f, rect.height);
|
||||
var rect1 = new Rect(rect0.xMax, rect.y, Styles.BUTTON_WIDTH, rect.height);
|
||||
var rect2 = new Rect(rect1.xMax, rect.y, Styles.BUTTON_WIDTH, rect.height);
|
||||
DrawSceneDropDown(rect0);
|
||||
DrawSceneLoadToggle(rect1);
|
||||
DrawSceneAddButton(rect2);
|
||||
|
|
@ -177,12 +62,12 @@ namespace Module.NavigationTool.Editor.Toolbar
|
|||
if (tempIsAdditive)
|
||||
{
|
||||
GUI.Label(rect, styles.iconSceneAdditive, styles.labelCenter);
|
||||
GUI.Label(rect, LABEL_SCENE_ADDITIVE, styles.labelCenter);
|
||||
GUI.Label(rect, Styles.LABEL_SCENE_ADDITIVE, styles.labelCenter);
|
||||
}
|
||||
else
|
||||
{
|
||||
GUI.Label(rect, styles.iconSceneSingle, styles.labelCenter);
|
||||
GUI.Label(rect, LABEL_SCENE_SINGLE, styles.labelCenter);
|
||||
GUI.Label(rect, Styles.LABEL_SCENE_SINGLE, styles.labelCenter);
|
||||
}
|
||||
|
||||
if (tempIsAdditive != isScenePickerSetAsAdditive)
|
||||
|
|
@ -211,17 +96,17 @@ namespace Module.NavigationTool.Editor.Toolbar
|
|||
}
|
||||
}
|
||||
|
||||
GUI.Label(rect, LABEL_SCENE_CREATE, styles.labelCenter);
|
||||
GUI.Label(rect, Styles.LABEL_SCENE_CREATE, styles.labelCenter);
|
||||
}
|
||||
|
||||
private static void ShowDropDown(Rect rect)
|
||||
{
|
||||
var menu = new GenericMenu();
|
||||
|
||||
for (var i = 0; i < SCENE_NAMES.Length; i++)
|
||||
for (var i = 0; i < SCENE_LIST.labels.Length; i++)
|
||||
{
|
||||
int sceneIndex = i;
|
||||
menu.AddItem(new GUIContent(SCENE_NAMES[i]), SELECTED_INDICES.Contains(i), () => SelectScene(sceneIndex));
|
||||
menu.AddItem(SCENE_LIST.labels[i], SCENE_LIST.selected.Contains(i), () => SelectScene(sceneIndex));
|
||||
}
|
||||
|
||||
menu.DropDown(rect);
|
||||
|
|
@ -231,30 +116,59 @@ namespace Module.NavigationTool.Editor.Toolbar
|
|||
{
|
||||
try
|
||||
{
|
||||
string path = SCENE_PATHS[index];
|
||||
Scene scene = SceneManager.GetSceneByPath(path);
|
||||
ScenePickerList.SceneElement scenes = SCENE_LIST.scenes[index];
|
||||
bool isScenePickerSetAsAdditive = ToolbarScenePickerSettings.IsScenePickerSetAsAdditive;
|
||||
|
||||
if (scene.isLoaded)
|
||||
{
|
||||
if (SceneManager.sceneCount == 1)
|
||||
return;
|
||||
|
||||
EditorSceneManager.CloseScene(scene, true);
|
||||
SELECTED_INDICES.Remove(index);
|
||||
}
|
||||
else if (isScenePickerSetAsAdditive)
|
||||
for (var i = 0; i < scenes.paths.Count; i++)
|
||||
{
|
||||
EditorSceneManager.OpenScene(SCENE_PATHS[index], OpenSceneMode.Additive);
|
||||
SELECTED_INDICES.Add(index);
|
||||
string path = scenes.paths[i];
|
||||
Scene scene = SceneManager.GetSceneByPath(path);
|
||||
|
||||
if (scenes.isGroup)
|
||||
{
|
||||
if (isScenePickerSetAsAdditive || i != 0)
|
||||
{
|
||||
EditorSceneManager.OpenScene(path, OpenSceneMode.Additive);
|
||||
int sceneIndex = SCENE_LIST.IndexOfPath(path, false);
|
||||
|
||||
if (sceneIndex != -1)
|
||||
SCENE_LIST.selected.Add(sceneIndex);
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorSceneManager.OpenScene(path, OpenSceneMode.Single);
|
||||
int sceneIndex = SCENE_LIST.IndexOfPath(path, false);
|
||||
|
||||
SCENE_LIST.selected.Clear();
|
||||
|
||||
if (sceneIndex != -1)
|
||||
SCENE_LIST.selected.Add(index);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (scene.isLoaded)
|
||||
{
|
||||
if (SceneManager.sceneCount == 1)
|
||||
return;
|
||||
|
||||
EditorSceneManager.CloseScene(scene, true);
|
||||
SCENE_LIST.selected.Remove(index);
|
||||
}
|
||||
else if (isScenePickerSetAsAdditive)
|
||||
{
|
||||
EditorSceneManager.OpenScene(path, OpenSceneMode.Additive);
|
||||
SCENE_LIST.selected.Add(index);
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorSceneManager.OpenScene(path, OpenSceneMode.Single);
|
||||
SCENE_LIST.selected.Clear();
|
||||
SCENE_LIST.selected.Add(index);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorSceneManager.OpenScene(SCENE_PATHS[index], OpenSceneMode.Single);
|
||||
SELECTED_INDICES.Clear();
|
||||
SELECTED_INDICES.Add(index);
|
||||
}
|
||||
|
||||
|
||||
RefreshSceneLabel();
|
||||
}
|
||||
catch (Exception e)
|
||||
|
|
@ -267,14 +181,14 @@ namespace Module.NavigationTool.Editor.Toolbar
|
|||
{
|
||||
STRING_BUILDER.Clear();
|
||||
|
||||
if (SELECTED_INDICES.Count != 0)
|
||||
if (SCENE_LIST.selected.Count != 0)
|
||||
{
|
||||
for (var i = 0; i < SELECTED_INDICES.Count; i++)
|
||||
for (var i = 0; i < SCENE_LIST.selected.Count; i++)
|
||||
{
|
||||
if (i > 0)
|
||||
STRING_BUILDER.Append(", ");
|
||||
|
||||
STRING_BUILDER.Append(SCENE_SHORT_NAMES[SELECTED_INDICES[i]]);
|
||||
STRING_BUILDER.Append(SCENE_LIST.scenes[SCENE_LIST.selected[i]].shortname);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -287,19 +201,20 @@ namespace Module.NavigationTool.Editor.Toolbar
|
|||
|
||||
public override float CalculateWidth()
|
||||
{
|
||||
return 100.0f + BUTTON_WIDTH * 2.0f;
|
||||
return 100.0f + Styles.BUTTON_WIDTH * 2.0f;
|
||||
}
|
||||
|
||||
public static void SetAsDirty()
|
||||
{
|
||||
IS_DIRTY = true;
|
||||
}
|
||||
|
||||
private sealed class SceneSortElement
|
||||
|
||||
private static class Styles
|
||||
{
|
||||
public readonly List<string> names = new List<string>();
|
||||
public readonly List<string> shortNames = new List<string>();
|
||||
public readonly List<string> paths = new List<string>();
|
||||
public static readonly GUIContent LABEL_SCENE_ADDITIVE = new GUIContent(string.Empty, "Additive scene loading (toogle to Single)");
|
||||
public static readonly GUIContent LABEL_SCENE_SINGLE = new GUIContent(string.Empty, "Single scene loading (toggle to Additive)");
|
||||
public static readonly GUIContent LABEL_SCENE_CREATE = new GUIContent(string.Empty, "Create a new scene");
|
||||
public const float BUTTON_WIDTH = 24.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue