Scene picker: Added option to add groups of scenes to open
This commit is contained in:
parent
41604b98e7
commit
a86f76904e
12
Editor/Toolbar/Settings/IToolbarProjectSettings.cs
Normal file
12
Editor/Toolbar/Settings/IToolbarProjectSettings.cs
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
namespace Module.NavigationTool.Editor.Toolbar
|
||||||
|
{
|
||||||
|
public interface IToolbarProjectSettings
|
||||||
|
{
|
||||||
|
string Title { get; }
|
||||||
|
bool IsSettingsDirty { get; }
|
||||||
|
|
||||||
|
void Initialize(ToolbarProjectSettings projectSettings);
|
||||||
|
void Draw();
|
||||||
|
void SetSettingsValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
3
Editor/Toolbar/Settings/IToolbarProjectSettings.cs.meta
Normal file
3
Editor/Toolbar/Settings/IToolbarProjectSettings.cs.meta
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: a45b77fff4244ae4a1271208dcb3bc9c
|
||||||
|
timeCreated: 1693423025
|
||||||
113
Editor/Toolbar/Settings/ToolbarProjectSettings.cs
Normal file
113
Editor/Toolbar/Settings/ToolbarProjectSettings.cs
Normal file
|
|
@ -0,0 +1,113 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Text;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace Module.NavigationTool.Editor.Toolbar
|
||||||
|
{
|
||||||
|
[Serializable]
|
||||||
|
public sealed class ToolbarProjectSettings
|
||||||
|
{
|
||||||
|
[SerializeField]
|
||||||
|
private List<string> keys = new();
|
||||||
|
[SerializeField]
|
||||||
|
private List<string> values = new();
|
||||||
|
|
||||||
|
public const string RELATIVE_PATH = "ProjectSettings/ToolbarProjectSettings.asset";
|
||||||
|
|
||||||
|
public void Load()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
string path = GetAbsolutePath();
|
||||||
|
|
||||||
|
if (File.Exists(path))
|
||||||
|
{
|
||||||
|
string json = File.ReadAllText(path);
|
||||||
|
JsonUtility.FromJsonOverwrite(json, this);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
keys.Clear();
|
||||||
|
values.Clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Debug.LogException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Save()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
string path = GetAbsolutePath();
|
||||||
|
string json = JsonUtility.ToJson(this, true);
|
||||||
|
File.WriteAllText(path, json, Encoding.Unicode);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Debug.LogException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public T GetValueAs<T>() where T : new()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
string key = typeof(T).FullName;
|
||||||
|
int index = keys.IndexOf(key);
|
||||||
|
|
||||||
|
if (index == -1)
|
||||||
|
{
|
||||||
|
var t = new T();
|
||||||
|
keys.Add(key);
|
||||||
|
values.Add(JsonUtility.ToJson(t));
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
string json = values[index];
|
||||||
|
return JsonUtility.FromJson<T>(json);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Debug.LogException(e);
|
||||||
|
return new T();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetValue<T>(T value) where T : new()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
string key = typeof(T).FullName;
|
||||||
|
string json = JsonUtility.ToJson(value);
|
||||||
|
int index = keys.IndexOf(key);
|
||||||
|
|
||||||
|
if (index != -1)
|
||||||
|
{
|
||||||
|
values[index] = json;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
keys.Add(key);
|
||||||
|
values.Add(json);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Debug.LogException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private string GetAbsolutePath()
|
||||||
|
{
|
||||||
|
string path = Application.dataPath;
|
||||||
|
path = path.Substring(0, Application.dataPath.Length - 6);
|
||||||
|
path += RELATIVE_PATH;
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
3
Editor/Toolbar/Settings/ToolbarProjectSettings.cs.meta
Normal file
3
Editor/Toolbar/Settings/ToolbarProjectSettings.cs.meta
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: a5fbb83f9c104775ae07b33244e133d2
|
||||||
|
timeCreated: 1693466538
|
||||||
110
Editor/Toolbar/Settings/ToolbarProjectSettingsProvider.cs
Normal file
110
Editor/Toolbar/Settings/ToolbarProjectSettingsProvider.cs
Normal file
|
|
@ -0,0 +1,110 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEditor;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace Module.NavigationTool.Editor.Toolbar
|
||||||
|
{
|
||||||
|
internal static class ToolbarProjectSettingsProvider
|
||||||
|
{
|
||||||
|
private static Styles STYLES;
|
||||||
|
private static IToolbarProjectSettings[] SETTINGS;
|
||||||
|
private static ToolbarProjectSettings PROJECT_SETTINGS;
|
||||||
|
private const string PREF_FOLDOUT_STATE = "ToolbarFoldout_{0}";
|
||||||
|
|
||||||
|
[SettingsProvider]
|
||||||
|
public static SettingsProvider GetProvider()
|
||||||
|
{
|
||||||
|
Initialize();
|
||||||
|
var keywords = new List<string> { "Toolbar" };
|
||||||
|
|
||||||
|
for (var i = 0; i < SETTINGS.Length; i++)
|
||||||
|
{
|
||||||
|
keywords.Add(SETTINGS[i].Title);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new SettingsProvider("Module/Toolbar", SettingsScope.Project)
|
||||||
|
{
|
||||||
|
label = "Toolbar",
|
||||||
|
keywords = keywords.ToArray(),
|
||||||
|
guiHandler = OnGui
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void Initialize()
|
||||||
|
{
|
||||||
|
if (STYLES == null)
|
||||||
|
STYLES = new Styles();
|
||||||
|
|
||||||
|
if (PROJECT_SETTINGS == null)
|
||||||
|
{
|
||||||
|
PROJECT_SETTINGS = new ToolbarProjectSettings();
|
||||||
|
PROJECT_SETTINGS.Load();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SETTINGS == null)
|
||||||
|
SETTINGS = ToolbarSettingsUtility.GetAllProjectSettings(PROJECT_SETTINGS);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void OnGui(string searchContext)
|
||||||
|
{
|
||||||
|
Initialize();
|
||||||
|
STYLES.Initialize(GUI.skin);
|
||||||
|
var isSettingsDirty = false;
|
||||||
|
|
||||||
|
EditorGUILayout.BeginVertical(STYLES.settingsGroup);
|
||||||
|
{
|
||||||
|
for (var i = 0; i < SETTINGS.Length; i++)
|
||||||
|
{
|
||||||
|
IToolbarProjectSettings settings = SETTINGS[i];
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
bool foldoutState = GetFoldoutState(settings);
|
||||||
|
bool newFoldoutState = EditorGUILayout.BeginFoldoutHeaderGroup(foldoutState, settings.Title, EditorStyles.foldoutHeader);
|
||||||
|
|
||||||
|
if (newFoldoutState)
|
||||||
|
{
|
||||||
|
EditorGUI.indentLevel++;
|
||||||
|
settings.Draw();
|
||||||
|
|
||||||
|
if (settings.IsSettingsDirty)
|
||||||
|
{
|
||||||
|
isSettingsDirty = true;
|
||||||
|
settings.SetSettingsValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
EditorGUI.indentLevel--;
|
||||||
|
}
|
||||||
|
|
||||||
|
EditorGUILayout.EndFoldoutHeaderGroup();
|
||||||
|
EditorGUILayout.Space();
|
||||||
|
|
||||||
|
if (newFoldoutState != foldoutState)
|
||||||
|
SetFoldoutState(settings, newFoldoutState);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
EditorGUILayout.LabelField(e.Message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isSettingsDirty)
|
||||||
|
PROJECT_SETTINGS.Save();
|
||||||
|
}
|
||||||
|
EditorGUILayout.EndVertical();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool GetFoldoutState(IToolbarProjectSettings settings)
|
||||||
|
{
|
||||||
|
string key = string.Format(PREF_FOLDOUT_STATE, settings.GetType().FullName);
|
||||||
|
return EditorPrefs.GetBool(key, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void SetFoldoutState(IToolbarProjectSettings settings, bool foldout)
|
||||||
|
{
|
||||||
|
string key = string.Format(PREF_FOLDOUT_STATE, settings.GetType().FullName);
|
||||||
|
EditorPrefs.SetBool(key, foldout);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 7e21927d181c41f1acdbecc9f5fc3e26
|
||||||
|
timeCreated: 1693423048
|
||||||
|
|
@ -36,7 +36,7 @@ namespace Module.NavigationTool.Editor.Toolbar
|
||||||
if (STYLES == null)
|
if (STYLES == null)
|
||||||
STYLES = new Styles();
|
STYLES = new Styles();
|
||||||
if (SETTINGS == null)
|
if (SETTINGS == null)
|
||||||
SETTINGS = ToolbarSettingsUtility.GetAllSettings();
|
SETTINGS = ToolbarSettingsUtility.GetAllUserSettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void OnGui(string searchContext)
|
private static void OnGui(string searchContext)
|
||||||
|
|
|
||||||
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 UnityEditor;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using UnityEditor;
|
|
||||||
using UnityEditorInternal;
|
|
||||||
using UnityEngine;
|
|
||||||
|
|
||||||
namespace Module.NavigationTool.Editor.Toolbar
|
namespace Module.NavigationTool.Editor.Toolbar
|
||||||
{
|
{
|
||||||
|
|
@ -12,7 +7,6 @@ namespace Module.NavigationTool.Editor.Toolbar
|
||||||
public string Title => "Scene";
|
public string Title => "Scene";
|
||||||
|
|
||||||
private const string PREF_IS_SCENE_ENABLED = "ToolbarSettings_IsSceneEnabled";
|
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";
|
private const string PREF_SCENE_PICKER_LOAD_SET_AS_ADDITIVE_KEY = "ToolbarSettings_ScenePickerLoadSetAsAdditive";
|
||||||
|
|
||||||
public static bool IsSceneEnabled
|
public static bool IsSceneEnabled
|
||||||
|
|
@ -21,78 +15,19 @@ namespace Module.NavigationTool.Editor.Toolbar
|
||||||
private set => EditorPrefs.SetBool(PREF_IS_SCENE_ENABLED, value);
|
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
|
public static bool IsScenePickerSetAsAdditive
|
||||||
{
|
{
|
||||||
get => EditorPrefs.GetBool(PREF_SCENE_PICKER_LOAD_SET_AS_ADDITIVE_KEY, false);
|
get => EditorPrefs.GetBool(PREF_SCENE_PICKER_LOAD_SET_AS_ADDITIVE_KEY, false);
|
||||||
set => EditorPrefs.SetBool(PREF_SCENE_PICKER_LOAD_SET_AS_ADDITIVE_KEY, value);
|
set => EditorPrefs.SetBool(PREF_SCENE_PICKER_LOAD_SET_AS_ADDITIVE_KEY, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ReorderableList assetLabelList;
|
|
||||||
private List<string> assetLabels;
|
|
||||||
|
|
||||||
public void Initialize()
|
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()
|
public void Draw()
|
||||||
{
|
{
|
||||||
IsSceneEnabled = EditorGUILayout.Toggle("Enable Scene picker", IsSceneEnabled);
|
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;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
|
||||||
using System.Runtime.CompilerServices;
|
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
using UnityEditor;
|
using UnityEditor;
|
||||||
|
|
@ -18,134 +15,22 @@ namespace Module.NavigationTool.Editor.Toolbar
|
||||||
public override bool Enabled => !EditorApplication.isPlaying && !EditorApplication.isPlayingOrWillChangePlaymode;
|
public override bool Enabled => !EditorApplication.isPlaying && !EditorApplication.isPlayingOrWillChangePlaymode;
|
||||||
public override EToolbarPlacement Placement => EToolbarPlacement.Right;
|
public override EToolbarPlacement Placement => EToolbarPlacement.Right;
|
||||||
public override int Priority => (int)EToolbarPriority.Medium;
|
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 bool IS_DIRTY = true;
|
||||||
|
|
||||||
private static void Initialize()
|
private static void Initialize()
|
||||||
{
|
{
|
||||||
if (!IS_DIRTY)
|
if (!IS_DIRTY)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
SELECTED_INDICES.Clear();
|
SCENE_LIST.Refresh();
|
||||||
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();
|
|
||||||
RefreshSceneLabel();
|
RefreshSceneLabel();
|
||||||
IS_DIRTY = false;
|
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()
|
public override void Update()
|
||||||
{
|
{
|
||||||
Initialize();
|
Initialize();
|
||||||
|
|
@ -155,9 +40,9 @@ namespace Module.NavigationTool.Editor.Toolbar
|
||||||
{
|
{
|
||||||
Initialize();
|
Initialize();
|
||||||
|
|
||||||
var rect0 = new Rect(rect.x, rect.y, rect.width - BUTTON_WIDTH * 2.0f, 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, BUTTON_WIDTH, rect.height);
|
var rect1 = new Rect(rect0.xMax, rect.y, Styles.BUTTON_WIDTH, rect.height);
|
||||||
var rect2 = new Rect(rect1.xMax, rect.y, BUTTON_WIDTH, rect.height);
|
var rect2 = new Rect(rect1.xMax, rect.y, Styles.BUTTON_WIDTH, rect.height);
|
||||||
DrawSceneDropDown(rect0);
|
DrawSceneDropDown(rect0);
|
||||||
DrawSceneLoadToggle(rect1);
|
DrawSceneLoadToggle(rect1);
|
||||||
DrawSceneAddButton(rect2);
|
DrawSceneAddButton(rect2);
|
||||||
|
|
@ -177,12 +62,12 @@ namespace Module.NavigationTool.Editor.Toolbar
|
||||||
if (tempIsAdditive)
|
if (tempIsAdditive)
|
||||||
{
|
{
|
||||||
GUI.Label(rect, styles.iconSceneAdditive, styles.labelCenter);
|
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
|
else
|
||||||
{
|
{
|
||||||
GUI.Label(rect, styles.iconSceneSingle, styles.labelCenter);
|
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)
|
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)
|
private static void ShowDropDown(Rect rect)
|
||||||
{
|
{
|
||||||
var menu = new GenericMenu();
|
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;
|
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);
|
menu.DropDown(rect);
|
||||||
|
|
@ -231,30 +116,59 @@ namespace Module.NavigationTool.Editor.Toolbar
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
string path = SCENE_PATHS[index];
|
ScenePickerList.SceneElement scenes = SCENE_LIST.scenes[index];
|
||||||
Scene scene = SceneManager.GetSceneByPath(path);
|
|
||||||
bool isScenePickerSetAsAdditive = ToolbarScenePickerSettings.IsScenePickerSetAsAdditive;
|
bool isScenePickerSetAsAdditive = ToolbarScenePickerSettings.IsScenePickerSetAsAdditive;
|
||||||
|
|
||||||
if (scene.isLoaded)
|
|
||||||
{
|
|
||||||
if (SceneManager.sceneCount == 1)
|
|
||||||
return;
|
|
||||||
|
|
||||||
EditorSceneManager.CloseScene(scene, true);
|
for (var i = 0; i < scenes.paths.Count; i++)
|
||||||
SELECTED_INDICES.Remove(index);
|
|
||||||
}
|
|
||||||
else if (isScenePickerSetAsAdditive)
|
|
||||||
{
|
{
|
||||||
EditorSceneManager.OpenScene(SCENE_PATHS[index], OpenSceneMode.Additive);
|
string path = scenes.paths[i];
|
||||||
SELECTED_INDICES.Add(index);
|
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();
|
RefreshSceneLabel();
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
|
|
@ -267,14 +181,14 @@ namespace Module.NavigationTool.Editor.Toolbar
|
||||||
{
|
{
|
||||||
STRING_BUILDER.Clear();
|
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)
|
if (i > 0)
|
||||||
STRING_BUILDER.Append(", ");
|
STRING_BUILDER.Append(", ");
|
||||||
|
|
||||||
STRING_BUILDER.Append(SCENE_SHORT_NAMES[SELECTED_INDICES[i]]);
|
STRING_BUILDER.Append(SCENE_LIST.scenes[SCENE_LIST.selected[i]].shortname);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
@ -287,19 +201,20 @@ namespace Module.NavigationTool.Editor.Toolbar
|
||||||
|
|
||||||
public override float CalculateWidth()
|
public override float CalculateWidth()
|
||||||
{
|
{
|
||||||
return 100.0f + BUTTON_WIDTH * 2.0f;
|
return 100.0f + Styles.BUTTON_WIDTH * 2.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void SetAsDirty()
|
public static void SetAsDirty()
|
||||||
{
|
{
|
||||||
IS_DIRTY = true;
|
IS_DIRTY = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private sealed class SceneSortElement
|
private static class Styles
|
||||||
{
|
{
|
||||||
public readonly List<string> names = new List<string>();
|
public static readonly GUIContent LABEL_SCENE_ADDITIVE = new GUIContent(string.Empty, "Additive scene loading (toogle to Single)");
|
||||||
public readonly List<string> shortNames = new List<string>();
|
public static readonly GUIContent LABEL_SCENE_SINGLE = new GUIContent(string.Empty, "Single scene loading (toggle to Additive)");
|
||||||
public readonly List<string> paths = new List<string>();
|
public static readonly GUIContent LABEL_SCENE_CREATE = new GUIContent(string.Empty, "Create a new scene");
|
||||||
|
public const float BUTTON_WIDTH = 24.0f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
3
Editor/Toolbar/Utilities/ReordableList.meta
Normal file
3
Editor/Toolbar/Utilities/ReordableList.meta
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: cf2b6dd510df4e818247e29339e154bc
|
||||||
|
timeCreated: 1693333131
|
||||||
|
|
@ -0,0 +1,76 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEditor;
|
||||||
|
using UnityEditorInternal;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace Module.NavigationTool.Editor.Toolbar
|
||||||
|
{
|
||||||
|
internal abstract class AbstractReordableListDrawer<T>
|
||||||
|
{
|
||||||
|
public readonly List<T> list;
|
||||||
|
|
||||||
|
private readonly ReorderableList reorderableList;
|
||||||
|
public event Action onChanged;
|
||||||
|
|
||||||
|
public bool IsDirty { get; private set; }
|
||||||
|
|
||||||
|
protected AbstractReordableListDrawer(List<T> list, string header)
|
||||||
|
{
|
||||||
|
this.list = list;
|
||||||
|
|
||||||
|
reorderableList = new ReorderableList(list, typeof(string), true, true, true, true);
|
||||||
|
reorderableList.drawElementCallback += (rect, index, isActive, isFocused) =>
|
||||||
|
{
|
||||||
|
EditorGUI.BeginChangeCheck();
|
||||||
|
OnDrawElement(rect, index, isActive, isFocused);
|
||||||
|
|
||||||
|
if (EditorGUI.EndChangeCheck())
|
||||||
|
IsDirty = true;
|
||||||
|
};
|
||||||
|
reorderableList.drawHeaderCallback += rect => EditorGUI.LabelField(rect, header);
|
||||||
|
reorderableList.onAddCallback += _ =>
|
||||||
|
{
|
||||||
|
OnAddElementToList();
|
||||||
|
InvokeChanged();
|
||||||
|
};
|
||||||
|
reorderableList.onRemoveCallback += rl =>
|
||||||
|
{
|
||||||
|
list.RemoveAt(rl.index);
|
||||||
|
OnRemovedElementFromList(rl.index);
|
||||||
|
InvokeChanged();
|
||||||
|
};
|
||||||
|
reorderableList.onReorderCallback += _ => InvokeChanged();;
|
||||||
|
reorderableList.elementHeightCallback += OnElementHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void DoList(Rect rect)
|
||||||
|
{
|
||||||
|
IsDirty = false;
|
||||||
|
reorderableList.DoList(rect);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void DoLayoutList()
|
||||||
|
{
|
||||||
|
IsDirty = false;
|
||||||
|
reorderableList.DoLayoutList();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract void OnDrawElement(Rect rect, int index, bool isActive, bool isFocused);
|
||||||
|
protected abstract void OnAddElementToList();
|
||||||
|
|
||||||
|
protected virtual void OnRemovedElementFromList(int index)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual float OnElementHeight(int index)
|
||||||
|
{
|
||||||
|
return EditorGUIUtility.singleLineHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void InvokeChanged()
|
||||||
|
{
|
||||||
|
onChanged?.Invoke();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: ad769ac53dd3476b82e6a2b62117c2d3
|
||||||
|
timeCreated: 1693332886
|
||||||
|
|
@ -0,0 +1,81 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEditor;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace Module.NavigationTool.Editor.Toolbar
|
||||||
|
{
|
||||||
|
internal sealed class SceneGroupReordableListDrawer : AbstractReordableListDrawer<SceneGroup>
|
||||||
|
{
|
||||||
|
private readonly List<StringReordableListDrawer> elements = new List<StringReordableListDrawer>();
|
||||||
|
|
||||||
|
public SceneGroupReordableListDrawer(List<SceneGroup> list, string header)
|
||||||
|
: base(list, header)
|
||||||
|
{
|
||||||
|
for (var i = 0; i < list.Count; i++)
|
||||||
|
{
|
||||||
|
elements.Add(new StringReordableListDrawer(list[i].filters, "Filters"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnDrawElement(Rect rect, int index, bool isActive, bool isFocused)
|
||||||
|
{
|
||||||
|
rect.height -= 2;
|
||||||
|
rect.y += 1;
|
||||||
|
|
||||||
|
SceneGroup group = list[index];
|
||||||
|
var rectName = new Rect(rect.x, rect.y, rect.width, EditorGUIUtility.singleLineHeight);
|
||||||
|
var rectType = new Rect(rect.x, rectName.yMax + 2f, rect.width, EditorGUIUtility.singleLineHeight);
|
||||||
|
var rectOptional = new Rect(rect.x, rectType.yMax + 2f, rect.width - 80f, EditorGUIUtility.singleLineHeight);
|
||||||
|
var rectOptionalBtn = new Rect(rectOptional.xMax, rectType.yMax + 2f, 80f, EditorGUIUtility.singleLineHeight);
|
||||||
|
var rectLabels = new Rect(rect.x, rectOptional.yMax + 2f, rect.width, rect.height - (rectName.y - rectOptional.yMax) - 4f);
|
||||||
|
|
||||||
|
EditorGUI.BeginChangeCheck();
|
||||||
|
group.name = EditorGUI.TextField(rectName, "Name", group.name);
|
||||||
|
group.optionalMainScenePath = EditorGUI.TextField(rectOptional, "Optional Main Scene Path", group.optionalMainScenePath);
|
||||||
|
|
||||||
|
if (GUI.Button(rectOptionalBtn, "Find"))
|
||||||
|
{
|
||||||
|
string mainScenePath = EditorUtility.OpenFilePanel("Scene", "Assets", "unity");
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(mainScenePath))
|
||||||
|
{
|
||||||
|
mainScenePath = mainScenePath.Substring(Application.dataPath.Length - 6);
|
||||||
|
group.optionalMainScenePath = mainScenePath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
group.filterType = (ESceneGroupFilterType)EditorGUI.EnumPopup(rectType, "Filter Type", group.filterType);
|
||||||
|
elements[index].DoList(rectLabels);
|
||||||
|
|
||||||
|
if (EditorGUI.EndChangeCheck())
|
||||||
|
InvokeChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnAddElementToList()
|
||||||
|
{
|
||||||
|
var filters = new List<string>();
|
||||||
|
|
||||||
|
list.Add(new SceneGroup
|
||||||
|
{
|
||||||
|
name = "New Scene Group",
|
||||||
|
filters = filters
|
||||||
|
});
|
||||||
|
|
||||||
|
elements.Add(new StringReordableListDrawer(filters, "Filters"));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnRemovedElementFromList(int index)
|
||||||
|
{
|
||||||
|
elements.RemoveAt(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override float OnElementHeight(int index)
|
||||||
|
{
|
||||||
|
int labelCount = list[index].filters.Count;
|
||||||
|
|
||||||
|
return base.OnElementHeight(index) * 3f
|
||||||
|
+ Mathf.Max(0, labelCount - 1) * (EditorGUIUtility.singleLineHeight + 2f)
|
||||||
|
+ 78f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 4923054c7113444ab1b696d769cdae00
|
||||||
|
timeCreated: 1693333828
|
||||||
|
|
@ -0,0 +1,35 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEditor;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace Module.NavigationTool.Editor.Toolbar
|
||||||
|
{
|
||||||
|
internal sealed class StringReordableListDrawer : AbstractReordableListDrawer<string>
|
||||||
|
{
|
||||||
|
public StringReordableListDrawer(List<string> list, string header)
|
||||||
|
: base(list, header)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnDrawElement(Rect rect, int index, bool isActive, bool isFocused)
|
||||||
|
{
|
||||||
|
rect.height -= 2;
|
||||||
|
rect.y += 1;
|
||||||
|
|
||||||
|
string text = list[index];
|
||||||
|
string temp = EditorGUI.TextField(rect, text);
|
||||||
|
|
||||||
|
if (string.Equals(text, temp, StringComparison.Ordinal))
|
||||||
|
return;
|
||||||
|
|
||||||
|
list[index] = temp;
|
||||||
|
InvokeChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnAddElementToList()
|
||||||
|
{
|
||||||
|
list.Add(string.Empty);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: e4b2250a66d548f1aacb916c7b5b6204
|
||||||
|
timeCreated: 1693333142
|
||||||
|
|
@ -7,7 +7,7 @@ namespace Module.NavigationTool.Editor.Toolbar
|
||||||
{
|
{
|
||||||
internal static class ToolbarSettingsUtility
|
internal static class ToolbarSettingsUtility
|
||||||
{
|
{
|
||||||
public static IToolbarSettings[] GetAllSettings()
|
public static IToolbarSettings[] GetAllUserSettings()
|
||||||
{
|
{
|
||||||
var list = new List<IToolbarSettings>(8);
|
var list = new List<IToolbarSettings>(8);
|
||||||
|
|
||||||
|
|
@ -43,5 +43,42 @@ namespace Module.NavigationTool.Editor.Toolbar
|
||||||
|
|
||||||
return list.ToArray();
|
return list.ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static IToolbarProjectSettings[] GetAllProjectSettings(ToolbarProjectSettings settings)
|
||||||
|
{
|
||||||
|
var list = new List<IToolbarProjectSettings>(8);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
|
||||||
|
Type iType = typeof(IToolbarProjectSettings);
|
||||||
|
|
||||||
|
for (var i = 0; i < assemblies.Length; i++)
|
||||||
|
{
|
||||||
|
Assembly assembly = assemblies[i];
|
||||||
|
Type[] types = assembly.GetTypes();
|
||||||
|
|
||||||
|
for (var j = 0; j < types.Length; j++)
|
||||||
|
{
|
||||||
|
Type type = types[j];
|
||||||
|
|
||||||
|
if (type.IsInterface || type.IsAbstract || !iType.IsAssignableFrom(type))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
var toolbar = (IToolbarProjectSettings)FormatterServices.GetUninitializedObject(type);
|
||||||
|
toolbar.Initialize(settings);
|
||||||
|
list.Add(toolbar);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
list.Sort((s0, s1) => string.Compare(s0.Title, s1.Title, StringComparison.Ordinal));
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
// Fail silently
|
||||||
|
}
|
||||||
|
|
||||||
|
return list.ToArray();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Loading…
Reference in a new issue