2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Unityエディタ拡張でLayerMaskFieldを表示する

Last updated at Posted at 2019-06-11

経緯

UnityのデフォルトのEditorGUILayoutにはLayerMaskを編集するAPIがなぜか無い( Layer自体を設定するAPIはある )ので自作する必要があったりする
参考ページ

サンプルスクリプト

以下のスクリプトを Unityのプロジェクト内にあるEditorフォルダ以下に配置すれば利用できる。
Editorフォルダに配置するとゲームロジック側で利用するスクリプト内部で#if UNITY_EDITORで括った箇所のエディタ拡張部分で呼び出しができない、( Editor拡張部だけをEditorフォルダ内に作る構成なら大丈夫なはず )

下の使い方スクリプトでも利用できるように書き換えました
ただこうすると通常のゲームロジック側でも呼び出せてしまうのでその際は実行ファイル出力時にビルドエラーが出るかも...いい方法ないかなぁ

#if UNITY_EDITOR

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

public static class MyEditorGUILayout
{
    
    // LayerMaskFieldはデフォルトでは無いので自作.
    public static LayerMask LayerMaskField(
        string label,
        LayerMask layerMask)
    {
        List<string> layers = new List<string>();
        List<int> layerNumbers = new List<int>();

        for (var i = 0; i < 32; ++i)
        {
            string layerName = LayerMask.LayerToName(i);
            if (!string.IsNullOrEmpty(layerName))
            {
                layers.Add(layerName);
                layerNumbers.Add(i);
            }
        }
        
        int maskWithoutEmpty = 0;
        for (var i = 0; i < layerNumbers.Count; ++i)
        {
            if (0 < ((1 << layerNumbers[i]) & layerMask.value))
                maskWithoutEmpty |= 1 << i;
        }

        maskWithoutEmpty = EditorGUILayout.MaskField(label, maskWithoutEmpty, layers.ToArray());
        int mask = 0;
        for (var i = 0; i < layerNumbers.Count; ++i)
        {
            if (0 < (maskWithoutEmpty & (1 << i)))
                mask |= 1 << layerNumbers[i];
        }
        layerMask.value = mask;

        return layerMask;
    }
}
#endif

使い方


using UnityEngine;
using System.Collections.Generic;
#if UNITY_EDITOR
using UnityEditor;
#endif

namespace sample
{
    public class Sample : MonoBehaviour
    {

        [SerializeField] LayerMask mask;
        
#if UNITY_EDITOR

        // エディタ拡張部分.
        [CustomEditor(typeof(Sample))]
        public class SampleEditor : Editor
        {

            public override void OnInspectorGUI()
            {
                var component = target as Sample;
                component.mask = MyEditorGUILayout.LayerMaskField("Layer Mask", component.mask);
            }
        }
        
#endif
        
    }
}


実行画面

上記サンプルスクリプトを実装すると以下のようになる
image.png

いつかデフォルトでサポートしてくれるといいなぁ

2
1
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?