🤖
[Unity] Property Drawerによるフィールドのカスタマイズ
作り方
-
UnityEngine.PropertyAttribute
を継承したC#クラスを作成します (これを仮に、SampleAttribute
とします) -
SampleAttribute
を描画するためのクラスとして、UnityEditor.PropertyDrawer
を継承したクラスを作成します (仮にSampleAttributeDrawer
とします) -
SampleAttributeDrawer
に属性としてUnityEditor.CustomPropertyDrawer
をつけます -
UnityEditor.CustomPropertyDrawer
のコンストラクターにある引数として、描画する対象の属性 (SampleAttribute
) の型を与えます
SampleAttribute.cs
// Inspectorウィンドウで表示している
// フィールドのラベルを任意に変更する
// という目的をもたせてみます
public class SampleAttribute : UnityEngine.PropertyAttribute {
/// <summary>
/// コンストラクタ
/// </summary>
/// <param name="label">ラベルとして表示するテキスト</param>
public SampleAttribute(string label) {
Label = label;
}
/// <summary>
/// ラベルに表示するテキスト
/// </summary>
public string Label { get; }
}
SampleAttributeDrawer.cs
[UnityEditor.CustomPropertyDrawer(typeof(SampleAttribute))]
public class SampleAttributeDrawer : UnityEditor.PropertyDrawer {
// 後述する描画を行うメンバー関数を追加します
}
IMGUIを使用して描画を行う
-
SampleAttributeDrawer
のメンバー関数としてSampleAttributeDrawer.GetPropertyHeight
とSampleAttributeDrawer.OnGUI
を作成します -
SampleAttributeDrawer.OnGUI
ではUnityEditor.EditorGUI
またはUnityEngine.GUI
を使用して描画をさせます -
SampleAttributeDrawer.GetPropertyHeight
で、SampleAttributeDrawer.OnGUI
内で描画した結果の合計となる高さを返却します
SampleAttributeDrawer.cs
[UnityEditor.CustomPropertyDrawer(typeof(SampleAttribute))]
public class SampleAttributeDrawer : UnityEditor.PropertyDrawer
{
/// <inheritdoc />
public override float GetPropertyHeight(
UnityEditor.SerializedProperty property,
UnityEngine.GUIContent label
)
{
// カスタム対象のAttributeに変換します
var labelAttribute = (SampleAttribute)attribute;
// (今回は)カスタムラベルの情報を作成します
var customLabel = new UnityEngine.GUIContent(labelAttribute.Label);
// 元の UnityEditor.SerializedProperty とカスタムしたラベルの高さを合わせて返却します
return UnityEditor.EditorGUI.GetPropertyHeight(
property: property,
label: customLabel,
includeChildren: true
);
}
/// <inheritdoc />
public override void OnGUI(
UnityEngine.Rect position,
UnityEditor.SerializedProperty property,
UnityEngine.GUIContent label
)
{
// カスタム対象のAttributeに変換します
var labelAttribute = (SampleAttribute)attribute;
// (今回は)カスタムラベルの情報を作成します
var customLabel = new UnityEngine.GUIContent(labelAttribute.Label);
// 元の UnityEditor.SerializedProperty とともにカスタムしたラベルで描画します
UnityEditor.EditorGUI.PropertyField(
position: position,
property: property,
label: customLabel,
includeChildren: true
);
}
}
UIToolKit (UIElements) で描画を行う
- SampleAttributeDrawer.CreatePropertyGUI を作成します
- 内部でVisualElementsを作成し、返却します
SampleAttributeDrawer.cs
[UnityEditor.CustomPropertyDrawer(typeof(SampleAttribute))]
public class SampleAttributeDrawer : UnityEditor.PropertyDrawer
{
/// <inheritdoc />
public override UnityEngine.UIElements.VisualElement CreatePropertyGUI(
UnityEditor.SerializedProperty property
)
{
// カスタム対象のAttributeに変換します
var labelAttribute = (SampleAttribute)attribute;
// カスタムしたラベル情報とともに、元のプロパティのUIElementを返却します
return new UnityEditor.UIElements.PropertyField(
property: property,
label: labelAttribute.Label
);
}
}
説明
「Property Drawer」(プロパティ ドロワー)はシリアライズ可能なフィールド(メンバ変数)を、UnityEditorのInspectorウィンドウ上など、GUIで「いい感じに」表示するために使われます。「いい感じ」というのは、プログラムで不都合な値が入らないよう制約をかけたり、フィールドの名称だけでは説明不足であるという理由で、マウスオーバーでそのフィールドを指した際に現れるツールチップスとしてテキストを加えるなどが可能です。
Inspector上にコンポーネントをカスタマイズして表示するUnityEditor.Editor
と違い、UnityEngine.PropertyAttribute
は特定のコンポーネントクラスに依存せず、属性を付与されたフィールドに対してカスタマイズを行うことができます。これによりカスタマイズした「Property Drawer」はさまざまなフィールドで使いまわすことができます。
環境
- Unity: 2021.3.4f1
- OS: Microsoft Windows 10 Home 10.0.19044
- CPU: Intel(R) Core(TM) i7-7700 CPU @ 3.60GHz
- GPU: NVIDIA GeForce GTX 1060 3GB
- RAM: 16.0 GB
- システムの種類: 64 ビット オペレーティング システム、x64 ベース プロセッサ
Discussion