シーン名を自動で作成する方法

2020年12月11日
エディタ拡張でシーン名を作成

この記事では、Unityでシーン名を自動で作成するエディタ拡張の作り方について説明します。

作り方

静的クラスを作成する

エディタ拡張のため、静的クラスを作ります。

public static class SceneNameScriptCreator
{
}

定数を宣言する

関数の実装に必要となる定数を宣言します。

private const string MENU_ITEM_NAME     = "Tools/Create/Scene Name";
private const string SCRIPT_FILE_PATH   = "Assets/Scripts/SceneName.cs";

シーン名を管理するスクリプトの文字列を作成する関数を定義する

ここで新たなusingディレクティブが必要となるため、下記のコードを一番上の行に追加します。

using System;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using UnityEditor;

そして、シーン名を管理するスクリプトの文字列を作成する関数を定義します。

private static string CreateScriptString() 
{
    var contents = EditorBuildSettings.scenes
        .Select( scene => Path.GetFileNameWithoutExtension( scene.path ) )
        .Distinct()
        .Aggregate( String.Empty, ( concatenated, scene_name ) => 
        {
            var adding_format_string    = @"    public const string {0} = ""{1}"";{2}";
            var constant_name           = ToSnakeCaseFromUpperCamelCase( scene_name );

            return concatenated + String.Format( 
                adding_format_string, 
                constant_name, 
                scene_name, 
                Environment.NewLine
            );
        } )
    ;

    var builder = new StringBuilder()
        .AppendLine( "/// <summary>" )
        .AppendLine( "/// シーンの名前を管理するクラス" )
        .AppendLine( "/// <summary>" )
        .AppendLine( "public static class SceneName" )
        .AppendLine( "{" )
        .Append( contents )
        .AppendLine( "}" )
    ;

    return builder.ToString();
}

private static string ToSnakeCaseFromUpperCamelCase( string value ) 
{
    return Regex.Replace( value, "([a-z])([A-Z])", "$1_$2" ).ToUpper();
}

ディレクトリが存在しない場合、作成する関数を定義する

Assets/Scripts」( ディレクトリ )が存在しない場合に作成する関数を定義します。

private static void CreateDirectoryIfNotExists() 
{
    var directory_path = Path.GetDirectoryName( SCRIPT_FILE_PATH );
    if( Directory.Exists( directory_path ) ) return;
    
    Directory.CreateDirectory( directory_path );
}

メニューの項目を追加する関数を定義する

最後にメニューに項目を追加するため、[MenuItem( MENU_ITEM_NAME )]の属性を付与した関数を定義します( ここでは「Create」という名前にします )。これでエディタ拡張のプログラムは完成です。

[MenuItem( MENU_ITEM_NAME )]
private static void Create() 
{
    if ( !CanCreate() ) return;

    CreateDirectoryIfNotExists();
    var script_string = CreateScriptString();

    File.WriteAllText( SCRIPT_FILE_PATH, script_string, Encoding.UTF8 );
    AssetDatabase.Refresh( ImportAssetOptions.ImportRecursive );

    EditorUtility.DisplayDialog( SCRIPT_FILE_PATH, "シーン名を作成しました。", "OK" );
}

private static bool CanCreate() => !EditorApplication.isPlaying && !EditorApplication.isCompiling;

使い方

エディタ拡張でシーン名を作成

上記のプログラムを作成すると、メニューに「Tools」>「Create」>「Scene Name」の項目ができます。

この項目を選択すると、「Assets/Scripts」( フォルダ )内に「SceneName.cs」という「シーン名を管理するクラス」が記述されたスクリプトが作成されます。

/// <summary>
/// シーンの名前を管理するクラス
/// <summary>
public static class SceneName
{
    public const string TITLE = "Title";
    public const string STAGE_SELECT = "StageSelect";
    public const string GAME = "Game";
    public const string RESULT = "Result";
    public const string SETTING = "Setting";
}

※ 作成されるスクリプトは、Build Settingsの「Scenes in Build」に設定されているシーンを対象にします。また、基となるシーンファイルは、アッパーキャメルケースでの命名を想定しています。

あとはこのクラス内の定数を任意の箇所で利用するだけです。

SceneManager.LoadScene( SceneName.GAME );

完成したプログラム

参考ページ