Unityで開発している時に、シーン名を定数文字列として持つクラスを作成することがあります。簡単な作業ですが、自動化できればありがたいなと思いEditor拡張を作りました。
BuildSettingsからScene一覧を取得する
まずは、BuildSettingsからビルドに登録されているシーン名一覧を取得します。
取得するコードは下記のようになります。
List<string> sceneNames = EditorBuildSettings.scenes
.Where(scene => scene.enabled)
.Select(scene => Path.GetFileNameWithoutExtension(scene.path))
.ToList();
シーン名一覧からクラスを生成する
シーン名一覧が取得できたので、それらを元にクラスの実装となる文字列を生成します。
namespaceあたりは適時自分の好みに変更すればいいかと思います。
private static string GenerateClassContent(List<string> sceneNames) { StringBuilder content = new StringBuilder(); content.Append("namespace Config {\n"); content.Append(" public class SceneNames {"); foreach (var sceneName in sceneNames) { content.Append($"\n public const string {sceneName} = \"{sceneName}\";"); } content.Append("\n }"); content.Append("\n}"); return content.ToString(); }
ファイルに書き込む
StreamWriterのインスタンスを生成して、先ほど生成したクラスのコンテンツを書き込みます。
Refreshを呼び出すことで、Editor上でリロードが走り自動生成されたファイルが作成されたことがわかります。
using (var sr = new StreamWriter(ScriptsFolderPath + "/Scripts/Config/SceneNames.cs")) { sr.Write(GenerateClassContent(sceneNames)); } AssetDatabase.Refresh();
スクリプト内容
最後に、私が実装したスクリプトを一例として載せておきます。
要点は上記で解説した通りですが、自分のお好みに編集して使いやすいようにEditor拡張を実装してみてください!
using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using UnityEditor; using UnityEngine; public class CreateSceneNames : EditorWindow { private static string ScriptsFolderPath => Application.dataPath + "/CustomAssets"; [MenuItem("Editor/Generate Scene Names Class")] private static void GenerateSceneNamesClass() { Debug.Log("GenerateSceneNamesClass is executing..."); List<string> sceneNames = EditorBuildSettings.scenes .Where(scene => scene.enabled) .Select(scene => Path.GetFileNameWithoutExtension(scene.path)) .ToList(); StringBuilder log = new StringBuilder(); foreach (var scene in sceneNames) { log.Append($"{scene}\n"); } Debug.Log($"Available scene names are\n{log}"); CreateSceneNamesClass(sceneNames); } private static void CreateSceneNamesClass(List<string> sceneNames) { if (Directory.Exists(ScriptsFolderPath + "/Scripts") == false) { Debug.Log("Scripts directory not found. Create New..."); Directory.CreateDirectory(ScriptsFolderPath + "/Scripts"); } if (Directory.Exists(ScriptsFolderPath + "/Scripts/Config") == false) { Debug.Log("Scripts/Config directory not found. Create new..."); Directory.CreateDirectory(ScriptsFolderPath + "/Scripts/Config"); } if (File.Exists(ScriptsFolderPath + "/Scripts/Config/SceneNames.cs") == false) { Debug.Log("Scripts/Config/SceneNames.cs not found. Create new..."); using (var sr = File.Create(ScriptsFolderPath + "/Scripts/Config/SceneNames.cs")) { } } using (var sr = new StreamWriter(ScriptsFolderPath + "/Scripts/Config/SceneNames.cs")) { sr.Write(GenerateClassContent(sceneNames)); } AssetDatabase.Refresh(); } private static string GenerateClassContent(List<string> sceneNames) { StringBuilder content = new StringBuilder(); content.Append("namespace Config {\n"); content.Append(" public class SceneNames {"); foreach (var sceneName in sceneNames) { content.Append($"\n public const string {sceneName} = \"{sceneName}\";"); } content.Append("\n }"); content.Append("\n}"); return content.ToString(); } }