【Unity】エディタ拡張で簡単にレイヤーマスクのフィールドを表示する

投稿者: | 2023-05-10

エディタウィンドウに簡単にレイヤーマスクを編集するフィールドを簡単に表示してみました。

レイヤーマスクの編集

カメラコンポーネント等はインスペクタにレイヤーマスクを編集できるドロップダウンが表示されます。

EditorGUILayoutには、レイヤーマスクを編集するためのフィールドがないので通常のビットマスクのフィールドで作ってみます。

EditorGUILayout.MaskField

ビットマスクを編集するフィールドはEditorGUILayout.MaskFieldメソッドで表示できます。第一引数にはドロップダウンの左に表示するテキスト、第二引数には現在のビットマスクの値、第三引数には各フラグの名前の配列を渡します。

なので、各レイヤー名の配列を作ればできると思います。

エディタウィンドウを作る

using System.Collections.Generic;
using UnityEngine;
using UnityEditor;

public class LayerMaskFieldTest : EditorWindow
{
    [MenuItem("Window/Test/LayerMaskFieldTest")]
    public static void CreateWindow()
    {
        var e = EditorWindow.GetWindow<LayerMaskFieldTest>();
        e.SetUp();
    }

    void SetUp()
    {
        layerMaskNames = GetLayerMaskNames();
    }

    // 現在のレイヤーマスク
    LayerMask layerMask;

    // レイヤー名の配列
    string[] layerMaskNames;

    private void OnGUI()
    {
        if (layerMaskNames == null) return;
        layerMask = EditorGUILayout.MaskField("レイヤーマスク", (int)layerMask, layerMaskNames);
    }

    // レイヤー名の配列を取得
    string[] GetLayerMaskNames()
    {
        var layers = new List<string>();

        for(int i = 0; i < 32; i++)
        {
            // i番目のレイヤー名
            string layerName = LayerMask.LayerToName(i);

            // 名前があればリストに追加
            if (layerName != "")
            {
                layers.Add(layerName);                 
            }
        }

        // 配列にして返す
        return layers.ToArray();
    }   
}

まずエディタウィンドウを表示するための静的メソッドにMenuItem属性をつけて、メインメニューから実行できるようにしています。

using System.Collections.Generic;
using UnityEngine;
using UnityEditor;

public class LayerMaskFieldTest : EditorWindow
{
    [MenuItem("Window/Test/LayerMaskFieldTest")]
    public static void CreateWindow()
    {
        var e = EditorWindow.GetWindow<LayerMaskFieldTest>();
        e.SetUp();
    }

    void SetUp()
    {
        layerMaskNames = GetLayerMaskNames();
    }

    // 現在のレイヤーマスク
    LayerMask layerMask;

    // レイヤー名の配列
    string[] layerMaskNames;

表示するとすぐに初期化のためのメソッドを呼んでいます。その中で、レイヤー名の配列を取得します。

レイヤーは最大で32個で、各レイヤーには0~31の整数が割り当てられています。LayerMask.LayerToNameメソッドの引数にその整数を渡すとレイヤー名が返ります。

そこでレイヤー名の配列を取得するメソッドでは、まずstringのリストを作り、各レイヤーの名前を確認して空文字でなければリストに追加しています。それを配列にして返します。

    string[] GetLayerMaskNames()
    {
        var layers = new List();

        for(int i = 0; i < 32; i++)
        {
            // i番目のレイヤー名
            string layerName = LayerMask.LayerToName(i);

            // 名前があればリストに追加
            if (layerName != "")
            {
                layers.Add(layerName);                 
            }
        }

        // 配列にして返す
        return layers.ToArray();
    }   

配列があれば、エディタウィンドウにマスクフィールドを表示します。ラベル名と、現在のレイヤーマスク、レイヤー名の配列を引数に渡して、戻り値を現在のレイヤーマスクの変数に入れます。

    private void OnGUI()
    {
        if (layerMaskNames == null) return;
        layerMask = EditorGUILayout.MaskField("レイヤーマスク", (int)layerMask, layerMaskNames);
    }

これで、エディタウィンドウにレイヤーマスクのフィールドを表示できました。

コメントを残す

メールアドレスが公開されることはありません。