🎚️

【Unity】フォルダ配下全てにラベルを設定するEditor拡張を作る

2021/04/19に公開

プロジェクトが大きくなってくると重宝する機能です。
手動でもラベルを付けることは出来ますが、階層が多いほど抜けも多くなりますし大変です。

Unityエディターのメニューバーに機能を追加して一瞬で終わらせましょう!

完成形

1.対象のフォルダにラベルを付ける

2.対象のフォルダを選択した上で、メニューバーのSetLabelを選択する

3.確認して開始する

4.少し待ったら終了!

たったこれだけの操作でこのフォルダ配下全てにラベルを付けることが出来ます!

ポイント

今回のポイントは、SetLabelAll()内に記述してある
AssetDatabase.SetLabels(obj, labels);
です。
これでラベルを付けます。

https://docs.unity3d.com/ja/current/ScriptReference/AssetDatabase.SetLabels.html

コード

全体像

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

public static class Label
{
    [MenuItem("Tools/SetLabel")]
    public static void SetLabel()
    {
        // 対象フォルダの配下全てにラベルをつける
        SetLabelChild();

        // 保存
        AssetDatabase.SaveAssets();
    }
    
    // 対象フォルダの配下全てにラベルをつける
    private static void SetLabelChild(){
        ...
    }
    
    // 選択しているフォルダを取得(複数化)
    private static List<string> GetChoiceParent(){
	...
    }
    
    // 選択しているフォルダ分ラベルを付ける
    private static void SetLabelChoiceAll(List<string> parentDirList){
        ...
    }
    
    // 対象フォルダのラベル取得
    private static string[] GetParentLabel(string parentDir){
        ...
    }
    
    // ラベルを付ける
    private static void SetLabelAll(string[] paths, string[] labels){
        ...
    }
    
    // 確認ポップアップ
    private static bool PopUp(List<string> parentDirList, string message, string ok, string cancel = ""){
	...
    }
}

対象フォルダの配下全てにラベルをつける

/// <summary>
/// 対象フォルダの配下全てにラベルをつける
/// </summary>
private static void SetLabelChild()
{
    // 選択しているフォルダを取得(複数化)
    List<string> parentDirList = GetChoiceParent();
    if (parentDirList.Count == 0) return;
    
    // 確認ポップアップ
    bool result = PopUp(parentDirList, "にラベルを付けますか?", "はい", "キャンセル");
    if (!result)
    {
    	Debug.Log("SetLabel:キャンセル");
    	return;
    }
    
    // 選択しているフォルダ分ラベルを付ける
    SetLabelChoiceAll(parentDirList);
    
    // 終了ポップアップ
    PopUp(parentDirList, "のラベル付けが終了しました", "終了");
}

選択しているフォルダを取得(複数化)

/// <summary>
/// 選択しているフォルダを取得(複数化)
/// </summary>
private static List<string> GetChoiceParent()
{
    List<string> parentDirList = new List<string>();

    if (Selection.objects.Length < 1)
    {
        Debug.Log("SetLabel:キャンセル");
	return parentDirList;
    }

    foreach (Object obj in Selection.objects)
    {
        string parentDir = AssetDatabase.GetAssetPath(obj);

        Debug.Log("filePath:" + parentDir);
        parentDirList.Add(parentDir);
    }
    return parentDirList;
}

選択しているフォルダ分ラベルを付ける

/// <summary>
/// 選択しているフォルダ分ラベルを付ける
/// </summary>
private static void SetLabelChoiceAll(List<string> parentDirList)
{
    // 選択しているフォルダ分処理する
    foreach (var item in parentDirList)
    {
        // 対象フォルダのラベル取得
        string[] parentLabels = GetParentLabel(item);
        
        // ラベルがついていれば実行
        if (parentLabels.Length > 0)
        {
            // 対象フォルダ以下にあるフォルダとオブジェクトをすべて取得する
            string[] allDirs = Directory.GetDirectories(item, "*", SearchOption.AllDirectories);
            string[] allFiles = Directory.GetFiles(item, "*", SearchOption.AllDirectories);
            
            //foreach (var allDir in allDirs)
            //{
            //    Debug.Log("allDir:" + allDir);
            //}
            //foreach (var allFile in allFiles)
            //{
            //    Debug.Log("allFile:" + allFile);
            //}
            
            // ラベルを付ける
            SetLabelAll(allDirs, parentLabels);
            SetLabelAll(allFiles, parentLabels);
        }
        else Debug.Log("SetLabel:選択したフォルダにラベルが付いていません");
    }
}

対象フォルダのラベル取得

/// <summary>
/// 対象フォルダのラベル取得
/// </summary>
private static string[] GetParentLabel(string parentDir)
{
    Object parentObj = AssetDatabase.LoadMainAssetAtPath(parentDir);
    string[] parentLabels = AssetDatabase.GetLabels(parentObj);
    
    //foreach (var parentLabel in parentLabels)
    //{
    //    Debug.Log("parentLabel:" + parentLabel);
    //}
    
    return parentLabels;
}

ラベルを付ける

/// <summary>
/// ラベルを付ける
/// </summary>
private static void SetLabelAll(string[] paths, string[] labels)
{
    foreach (var path in paths)
    {
	// metaは無視
        string ext = Path.GetExtension(path);
        if (ext == ".meta") continue;

        Object obj = AssetDatabase.LoadMainAssetAtPath(path);
        AssetDatabase.SetLabels(obj, labels);
    }
}

確認ポップアップ

/// <summary>
/// 確認ポップアップ
/// </summary>
private static bool PopUp(List<string> parentDirList, string message, string ok, string cancel = "")
{
    string parentDir = "";
    foreach (var item in parentDirList)
    {
        string[] arr = item.Split('/');
        parentDir += arr[arr.Length - 1] + "\n";
    }

    if (cancel == "")
    {
        bool result = EditorUtility.DisplayDialog("SetLabel", parentDir + message, ok);
        return result;
    }
    else
    {
        bool result = EditorUtility.DisplayDialog("SetLabel", parentDir + message, ok, cancel);
        return result;
    }
}

終わりに

ポップアップは分かりやすさのために表示しています。
プログレスバーを付けて進捗状況を確認出来るようにしてもいいですね。
自分好みにアレンジしてみて下さい!

いいねして頂けると励みになるので是非お願いします!

Discussion