Scene Picker: Modified scene groups to contain LoadAsGroup, SortAsGroup and SortInSubmenuAsGroup

### Changed
-  Scene groups to contain three different types of behaviours for grouping:
   - Load As Group: Groups all scenes into a single entry
   - Sort As Group: Sorts all scenes into entries close to each other in the dropdown
   - Sort In Submenu As Group: Sorts all scenes into entries in a submenu

### Removed
- Removed "Scene sorting by Asset label" groups
This commit is contained in:
Anders Ejlersen 2025-03-29 11:12:03 +01:00
parent a7cb8e885b
commit dd80d46ebb
11 changed files with 128 additions and 71 deletions

View file

@ -2,16 +2,30 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
## [1.11.0] - 2025-03-29
### Changed
- Scene groups to contain three different types of behaviours for grouping:
- Load As Group: Groups all scenes into a single entry
- Sort As Group: Sorts all scenes into entries close to each other in the dropdown
- Sort In Submenu As Group: Sorts all scenes into entries in a submenu
### Removed
- Removed "Scene sorting by Asset label" groups
## [1.10.2] - 2024-11-25 ## [1.10.2] - 2024-11-25
### Fixed ### Fixed
- Fixed issue, where scene picker would not prompt about unsaved scene changes - Fixed issue, where scene picker would not prompt about unsaved scene changes
## [1.10.1] - 2024-11-25 ## [1.10.1] - 2024-11-25
### Fixed ### Fixed
- Fixed issue, where scene picker settings wouldn't save, if removing a group element - Fixed issue, where scene picker settings wouldn't save, if removing a group element
## [1.10.0] - 2024-11-17 ## [1.10.0] - 2024-11-17
### Added ### Added

View file

@ -4,7 +4,7 @@ using UnityEditor.Overlays;
namespace Module.NavigationTool.Editor.SceneViewToolbar namespace Module.NavigationTool.Editor.SceneViewToolbar
{ {
[Overlay(typeof(SceneView), "unity-custom-tool-handle-utility", "Custom/Tool Settings", true)] [Overlay(typeof(SceneView), "unity-custom-tool-handle-utility", "Custom/Tool Settings")]
internal sealed class EditorSceneViewToolHandleOverlay : ToolbarOverlay internal sealed class EditorSceneViewToolHandleOverlay : ToolbarOverlay
{ {
public EditorSceneViewToolHandleOverlay() public EditorSceneViewToolHandleOverlay()

View file

@ -0,0 +1,9 @@
namespace Module.NavigationTool.Editor.Toolbar
{
public enum ESceneGroupBehaviourType
{
LoadAsGroup,
SortAsGroup,
SortInSubmenuAsGroup
}
}

View file

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 71206076ab694b109f3391c4f28bc506
timeCreated: 1743238963

View file

@ -8,7 +8,9 @@ namespace Module.NavigationTool.Editor.Toolbar
{ {
public string name; public string name;
public ESceneGroupFilterType filterType; public ESceneGroupFilterType filterType;
public ESceneGroupBehaviourType behaviourType;
public string optionalMainScenePath; public string optionalMainScenePath;
public string subMenuPath = "Submenu";
public List<string> filters = new(); public List<string> filters = new();
} }
} }

View file

@ -24,7 +24,6 @@ namespace Module.NavigationTool.Editor.Toolbar
List<WorkingSetScene> assets = GetWorkingSet(); List<WorkingSetScene> assets = GetWorkingSet();
FetchAllScenesFromBuildSettings(assets); FetchAllScenesFromBuildSettings(assets);
FetchAllScenesFromLabels(assets, settings.labels);
FetchAllScenesFromSceneGroups(assets, settings.sceneGroups); FetchAllScenesFromSceneGroups(assets, settings.sceneGroups);
FetchAllRemainingScenes(assets); FetchAllRemainingScenes(assets);
@ -49,32 +48,9 @@ namespace Module.NavigationTool.Editor.Toolbar
}); });
} }
} }
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) 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++) for (var i = 0; i < sceneGroups.Count; i++)
{ {
SceneGroup sceneGroup = sceneGroups[i]; SceneGroup sceneGroup = sceneGroups[i];
@ -95,28 +71,73 @@ namespace Module.NavigationTool.Editor.Toolbar
name = sceneGroup.name.Replace("/", "\\"); name = sceneGroup.name.Replace("/", "\\");
} }
if (!string.IsNullOrEmpty(sceneGroup.optionalMainScenePath)) if (sceneGroup.behaviourType == ESceneGroupBehaviourType.LoadAsGroup)
SetWorkingSceneAsFirst(filteredScenes, sceneGroup.optionalMainScenePath);
filteredScenes = FilterToUniques(filteredScenes);
var scene = new SceneElement
{ {
name = name, if (sceneGroups.Count != 0)
shortname = name, scenes.Add(new SceneElement{ includeAsSelectable = false });
isGroup = true
}; if (!string.IsNullOrEmpty(sceneGroup.optionalMainScenePath))
SetWorkingSceneAsFirst(filteredScenes, sceneGroup.optionalMainScenePath);
for (var j = 0; j < filteredScenes.Count; j++)
{ filteredScenes = FilterToUniques(filteredScenes);
scene.paths.Add(filteredScenes[j].path);
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);
}
else if (sceneGroup.behaviourType == ESceneGroupBehaviourType.SortAsGroup)
{
filteredScenes = FilterToUniques(filteredScenes);
filteredScenes = FilterAllExcept(filteredScenes, scenes);
if (filteredScenes.Count != 0)
scenes.Add(new SceneElement{ includeAsSelectable = false });
for (var j = 0; j < filteredScenes.Count; j++)
{
scenes.Add(new SceneElement
{
name = filteredScenes[j].name,
shortname = filteredScenes[j].shortname,
paths = { filteredScenes[j].path }
});
}
}
else if (sceneGroup.behaviourType == ESceneGroupBehaviourType.SortInSubmenuAsGroup)
{
if (string.IsNullOrEmpty(sceneGroup.subMenuPath))
continue;
filteredScenes = FilterToUniques(filteredScenes);
filteredScenes = FilterAllExcept(filteredScenes, scenes);
if (filteredScenes.Count != 0)
scenes.Add(new SceneElement{ includeAsSelectable = false });
for (var j = 0; j < filteredScenes.Count; j++)
{
scenes.Add(new SceneElement
{
name = $"{sceneGroup.subMenuPath}/{filteredScenes[j].name}",
shortname = filteredScenes[j].shortname,
paths = { filteredScenes[j].path }
});
}
} }
scene.name += $" ({scene.paths.Count})";
scenes.Add(scene);
} }
} }
private void FetchAllRemainingScenes(List<WorkingSetScene> assets) private void FetchAllRemainingScenes(List<WorkingSetScene> assets)
{ {
List<WorkingSetScene> filteredScenes = FilterAllExcept(assets, scenes); List<WorkingSetScene> filteredScenes = FilterAllExcept(assets, scenes);

View file

@ -1,5 +1,4 @@
using System; using System;
using System.Collections.Generic;
namespace Module.NavigationTool.Editor.Toolbar namespace Module.NavigationTool.Editor.Toolbar
{ {
@ -8,7 +7,6 @@ namespace Module.NavigationTool.Editor.Toolbar
public string Title => "Scene"; public string Title => "Scene";
public bool IsSettingsDirty { get; private set; } public bool IsSettingsDirty { get; private set; }
private StringReorderableListDrawer assetLabelList;
private SceneGroupReorderableListDrawer sceneGroupList; private SceneGroupReorderableListDrawer sceneGroupList;
private ToolbarProjectSettings projectSettings; private ToolbarProjectSettings projectSettings;
@ -19,18 +17,14 @@ namespace Module.NavigationTool.Editor.Toolbar
this.projectSettings = projectSettings; this.projectSettings = projectSettings;
settings = projectSettings.GetValueAs<Settings>(); settings = projectSettings.GetValueAs<Settings>();
assetLabelList = new StringReorderableListDrawer(settings.labels, "Scene sorting by Asset label");
assetLabelList.onChanged += ToolScenePicker.SetAsDirty;
sceneGroupList = new SceneGroupReorderableListDrawer(settings.sceneGroups.groups, "Scene groups"); sceneGroupList = new SceneGroupReorderableListDrawer(settings.sceneGroups.groups, "Scene groups");
sceneGroupList.onChanged += ToolScenePicker.SetAsDirty; sceneGroupList.onChanged += ToolScenePicker.SetAsDirty;
} }
public void Draw() public void Draw()
{ {
assetLabelList.DoLayoutList();
sceneGroupList.DoLayoutList(); sceneGroupList.DoLayoutList();
IsSettingsDirty = assetLabelList.IsDirty || sceneGroupList.IsDirty; IsSettingsDirty = sceneGroupList.IsDirty;
} }
public void SetSettingsValue() public void SetSettingsValue()
@ -41,7 +35,6 @@ namespace Module.NavigationTool.Editor.Toolbar
[Serializable] [Serializable]
public sealed class Settings public sealed class Settings
{ {
public List<string> labels = new();
public SceneGroupArray sceneGroups = new(); public SceneGroupArray sceneGroups = new();
} }
} }

View file

@ -1,7 +1,6 @@
using JetBrains.Annotations; using JetBrains.Annotations;
using UnityEditor; using UnityEditor;
using UnityEngine; using UnityEngine;
using UTools = UnityEditor.Tools;
namespace Module.NavigationTool.Editor.Toolbar namespace Module.NavigationTool.Editor.Toolbar
{ {

View file

@ -24,26 +24,39 @@ namespace Module.NavigationTool.Editor.Toolbar
SceneGroup group = list[index]; SceneGroup group = list[index];
var rectName = new Rect(rect.x, rect.y, rect.width, EditorGUIUtility.singleLineHeight); 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 rectBehaviourType = 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 rectType = new Rect(rect.x, rectBehaviourType.yMax + 2f, rect.width, EditorGUIUtility.singleLineHeight);
var rectOptionalBtn = new Rect(rectOptional.xMax, rectType.yMax + 2f, 80f, EditorGUIUtility.singleLineHeight); var rectLabels = new Rect(rect.x, rectType.yMax + 2f, rect.width, rect.height - (rectName.y - rectType.yMax) - 4f);
var rectLabels = new Rect(rect.x, rectOptional.yMax + 2f, rect.width, rect.height - (rectName.y - rectOptional.yMax) - 4f);
EditorGUI.BeginChangeCheck(); EditorGUI.BeginChangeCheck();
group.name = EditorGUI.TextField(rectName, "Name", group.name); group.name = EditorGUI.TextField(rectName, "Name", group.name);
group.optionalMainScenePath = EditorGUI.TextField(rectOptional, "Optional Main Scene Path", group.optionalMainScenePath);
if (group.behaviourType == ESceneGroupBehaviourType.LoadAsGroup)
if (GUI.Button(rectOptionalBtn, "Find"))
{ {
string mainScenePath = EditorUtility.OpenFilePanel("Scene", "Assets", "unity"); 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);
rectLabels = new Rect(rect.x, rectOptional.yMax + 2f, rect.width, rect.height - (rectName.y - rectOptional.yMax) - 4f);
group.optionalMainScenePath = EditorGUI.TextField(rectOptional, "Optional Main Scene Path", group.optionalMainScenePath);
if (!string.IsNullOrEmpty(mainScenePath)) if (GUI.Button(rectOptionalBtn, "Find"))
{ {
mainScenePath = mainScenePath.Substring(Application.dataPath.Length - 6); string mainScenePath = EditorUtility.OpenFilePanel("Scene", "Assets", "unity");
group.optionalMainScenePath = mainScenePath;
if (!string.IsNullOrEmpty(mainScenePath))
{
mainScenePath = mainScenePath.Substring(Application.dataPath.Length - 6);
group.optionalMainScenePath = mainScenePath;
}
} }
} }
else if (group.behaviourType == ESceneGroupBehaviourType.SortInSubmenuAsGroup)
{
var rectOptional = new Rect(rect.x, rectType.yMax + 2f, rect.width, EditorGUIUtility.singleLineHeight);
rectLabels = new Rect(rect.x, rectOptional.yMax + 2f, rect.width, rect.height - (rectName.y - rectOptional.yMax) - 4f);
group.subMenuPath = EditorGUI.TextField(rectOptional, "Sub-menu Path", group.subMenuPath);
}
group.behaviourType = (ESceneGroupBehaviourType)EditorGUI.EnumPopup(rectBehaviourType, "Behaviour Type", group.behaviourType);
group.filterType = (ESceneGroupFilterType)EditorGUI.EnumPopup(rectType, "Filter Type", group.filterType); group.filterType = (ESceneGroupFilterType)EditorGUI.EnumPopup(rectType, "Filter Type", group.filterType);
elements[index].DoList(rectLabels); elements[index].DoList(rectLabels);
@ -75,7 +88,7 @@ namespace Module.NavigationTool.Editor.Toolbar
return base.OnElementHeight(index) * 3f return base.OnElementHeight(index) * 3f
+ Mathf.Max(0, labelCount - 1) * (EditorGUIUtility.singleLineHeight + 2f) + Mathf.Max(0, labelCount - 1) * (EditorGUIUtility.singleLineHeight + 2f)
+ 78f; + 104f;
} }
} }
} }

View file

@ -22,12 +22,15 @@ Toolbars to the left and right of the play-buttons. Anything can be added, as lo
Several tools are available from start: Several tools are available from start:
* UI Layer: Toggle the UI layer on/off * Build: Select build target and build
* UI Canvas: Select and center the camera on any Canvases in the scene
* Scene: Load any scene in the project easily by using the dropdown
* Time Scale: Adjust the time scale from [0;1] from a slider
* Target Frame Rate Scale: Adjust target frame rate from [10;144] from a slider
* Player Prefs: Delete all PlayerPrefs data * Player Prefs: Delete all PlayerPrefs data
* Scene: Load any scene in the project easily by using the dropdown
* Target Frame Rate Scale: Adjust target frame rate from [10;144] from a slider
* Time Scale: Adjust the time scale from [0;1] from a slider
* UI Canvas: Select and center the camera on any Canvases in the scene
* UI Layer: Toggle the UI layer on/off
* Settings: Open project or preferences
* Save: Project save
### Customization ### Customization

View file

@ -1,6 +1,6 @@
{ {
"name": "com.module.navigationtool", "name": "com.module.navigationtool",
"version": "1.10.2", "version": "1.11.0",
"displayName": "Module.NavigationTool", "displayName": "Module.NavigationTool",
"description": "Support for navigation tools, like favorites, history and toolbars", "description": "Support for navigation tools, like favorites, history and toolbars",
"unity": "2019.2", "unity": "2019.2",