Instantly share code, notes, and snippets.
Created
July 17, 2023 13:23
-
Star
(0)
0
You must be signed in to star a gist -
Fork
(0)
0
You must be signed in to fork a gist
-
Save darktable/26e95842c572f97af13aacc03b79f2e2 to your computer and use it in GitHub Desktop.
Utility script to generate a menu items to load the scenes included in build settings.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// The contents of this file is free and unencumbered software released into the | |
// public domain. For more information, please refer to <http://unlicense.org/> | |
using System; | |
using System.IO; | |
using System.Text; | |
using UnityEditor; | |
using UnityEngine; | |
using UnityEngine.SceneManagement; | |
namespace DarkTable.Utils | |
{ | |
/// <summary> | |
/// Generates a menu of *only* the scenes that are included in the build. | |
/// </summary> | |
public class GenerateSceneLoaderMenu : AssetModificationProcessor | |
{ | |
private const string k_Header = "/* <auto-generated> DO NOT MODIFY\n (created by GenerateSceneLoaderMenu.cs. File->Save Project will usually trigger an update of this file) */\n\n"; | |
private const string k_StandardAssets = "Standard Assets"; | |
private const string k_DirectoryName = "Editor/Scripts/SceneLoaderMenu"; | |
private const string k_FileName = "SceneLoaderMenu.cs"; | |
private static readonly string[] k_SavedAssets = new[] { "EditorBuildSettings.asset" }; | |
[InitializeOnLoadMethod] | |
private static void Initialize() | |
{ | |
string rootPath = Path.Combine(Application.dataPath, k_StandardAssets, k_DirectoryName); | |
if (!Directory.Exists(rootPath)) | |
{ | |
UpdateSceneList(); | |
return; | |
} | |
string fileName = Path.Combine(rootPath, k_FileName); | |
if (!File.Exists(fileName)) | |
{ | |
UpdateSceneList(); | |
} | |
} | |
private static string[] OnWillSaveAssets(string[] paths) | |
{ | |
foreach (string path in paths) | |
{ | |
string filename = Path.GetFileName(path); | |
foreach (string asset in k_SavedAssets) | |
{ | |
if (filename.Equals(asset, StringComparison.InvariantCultureIgnoreCase)) | |
{ | |
UpdateSceneList(); | |
return paths; | |
} | |
} | |
} | |
return paths; | |
} | |
private static void UpdateSceneList() | |
{ | |
var outfile = new StringBuilder(k_Header, 4096); | |
int count = SceneManager.sceneCountInBuildSettings; | |
AddClassHeader(outfile); | |
for (var i = 0; i < count; i++) | |
{ | |
string scenePath = SceneUtility.GetScenePathByBuildIndex(i); | |
if (string.IsNullOrEmpty(scenePath)) | |
{ | |
continue; | |
} | |
AddCodeForFile(scenePath, outfile); | |
} | |
AddClassFooter(outfile); | |
SaveFile(outfile); | |
void AddClassHeader(StringBuilder output) | |
{ | |
output.Append("using UnityEditor;\n") | |
.Append("using UnityEditor.SceneManagement;\n\n") | |
.Append("public static class SceneLoaderMenu {\n"); | |
} | |
void AddClassFooter(StringBuilder output) | |
{ | |
output.Append(" private static void OpenScene(string guid) {\n") | |
.Append(" if (EditorSceneManager.SaveCurrentModifiedScenesIfUserWantsTo()) {\n") | |
.Append(" EditorSceneManager.OpenScene(AssetDatabase.GUIDToAssetPath(guid), OpenSceneMode.Single);\n") | |
.Append(" }\n }\n}\n"); | |
} | |
void AddCodeForFile(String scenePath, StringBuilder output) | |
{ | |
scenePath = scenePath.Replace('\\', '/'); | |
var directoryName = ObjectNames.NicifyVariableName(Path.GetFileName(Path.GetDirectoryName(scenePath))); | |
var sceneName = ObjectNames.NicifyVariableName(Path.GetFileNameWithoutExtension(scenePath)); | |
if (!string.IsNullOrEmpty(directoryName) | |
&& !directoryName.Equals("Assets", StringComparison.InvariantCultureIgnoreCase) | |
&& !directoryName.Equals("Scenes", StringComparison.InvariantCultureIgnoreCase)) | |
{ | |
sceneName = $"{directoryName}/{sceneName}"; | |
} | |
var guid = AssetDatabase.GUIDFromAssetPath(scenePath); | |
output.Append($" [MenuItem(\"Tools/Load Scene/{sceneName}\")]\n") | |
.Append($" public static void Load_{guid}() => OpenScene(\"{guid}\");\n\n"); | |
} | |
} | |
private static void SaveFile(StringBuilder outfile) | |
{ | |
string rootPath = Path.Combine(Application.dataPath, k_StandardAssets, k_DirectoryName); | |
if (!Directory.Exists(rootPath)) | |
{ | |
Directory.CreateDirectory(rootPath); | |
} | |
string filePath = Path.Combine(rootPath, k_FileName); | |
string current = null; | |
if (File.Exists(filePath)) | |
{ | |
current = File.ReadAllText(filePath); | |
} | |
var updated = outfile.ToString(); | |
if (!string.Equals(current, updated)) | |
{ | |
Debug.Log("Generating scene loader file"); | |
File.WriteAllText(filePath, updated); | |
AssetDatabase.Refresh(); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment