経緯
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
}
}
実行画面
いつかデフォルトでサポートしてくれるといいなぁ