夜風のMixedReality

xRと出会って変わった人生と出会った技術を書き残すためのGeekなHoloRangerの居場所

Unityエディタ拡張でファイル構造のテンプレートを生成する

本日はUnity枠です。

Unityでは基本的にAssets内に3Dモデルやプレファブ、C#スクリプトを配置します。

この際に一般的にはフォルダ分けしてわかりやすいように格納するのですが筆者の場合ファイル整理が得意ではないため、コマンドでテンプレート化したフォルダを生成するツールを作ります。

〇C#からフォルダの作成

C#からフォルダを作成するためにはAssetDatabase.CreateFolder()を使用します。

docs.unity3d.com

AssetsDatabase.CreateFolderは2つの引数を持つことができ、1つ目の引数でパス(親オブジェクト)、二つ目のパスでフォルダの名前を指定します。

なおパスはAssetsから始まるパスである必要があります。

例えばAssets直下にフォルダを作成したい場合は次のようになります。

 AssetDatabase.CreateFolder("Assets", "New Folder");

〇テンプレートの作成

今回はfloderNamesという変数名のstring配列にテンプレートを指定します。

     string[] folderNames = new string[] { "Mesh", "Materials", "Textures", "Prefabs", "Others" };

for文でフォルダの数処理を回します。 AssetDatabase.GenerateUniqueAssetPathは引数のパスにこれから作成する第二引数で指定した名前と同じファイルがないかどうかをチェックするメソッドです。

オブジェクト等を複製した場合○○ 1という名前の複製後ファイルになりますが、これを行っているのがこのメソッドで、同一名のファイルが存在しないようにする仕組みです。

        for (int i = 0; i < folderNames.Length; i++) {
string newFolderPath = AssetDatabase.GenerateUniqueAssetPath(Path.Combine(パス, folderNames[i]));
            AssetDatabase.CreateFolder(パス, folderNames[i]);
        }

次にパスですが、これは現在開いているProjectWindowの階層を指定する必要があります。

これはAssetFatabase.GetAssetPathから取得可能です。

 string selectedPath = AssetDatabase.GetAssetPath(Selection.activeObject);

これによって現在開かれている階層にStringの配列で指定した数for文でフォルダが作成されるようになります。

後はUnityEditor拡張の仕組みにのっとってメソッドに [MenuItem("Assets/Create/3DTemplateFolders",priority = 1)]属性をつけることでCreateウィンドウからコマンドを実行可能になります。

〇コード一覧

コード一覧表示

using UnityEditor;
using System.IO;

/// <summary>
/// Creates a templated folder structure for creating 3D models in the path of the currently open project window.
/// </summary>
public class CreateFolders : MonoBehaviour {
    [MenuItem("Assets/Create/3DTemplateFolders",priority = 1)]
    public static void CreateNewFolders() {
        string selectedPath = AssetDatabase.GetAssetPath(Selection.activeObject);
        if (string.IsNullOrEmpty(selectedPath)) {
            selectedPath = "Assets";
        }
        string[] folderNames = new string[] { "Mesh", "Materials", "Textures", "Prefabs", "Others" };
        for (int i = 0; i < folderNames.Length; i++) {
            string newFolderPath = AssetDatabase.GenerateUniqueAssetPath(Path.Combine(selectedPath, folderNames[i]));
            AssetDatabase.CreateFolder(selectedPath, folderNames[i]);
            Debug.Log($"Created folder: {newFolderPath}");
        }
        
        AssetDatabase.Refresh();
    }
}