カスタムプロパティードローワーの基底クラスです。作成した Serializable クラスや PropertyAttribute 変数のカスタムドローワーを作成して使用することができます。
PropertyDrawers have two uses:
- Customize the GUI of every instance of a Serializable class.
- PropertyAttribute の付いたスクリプトメンバーの GUI をカスタマイズ
If you have a custom Serializable class, you can use a PropertyDrawer to control how it looks in the Inspector.
Consider the Serializable class Ingredient in the script below:
using System; using UnityEngine;
public enum IngredientUnit { Spoon, Cup, Bowl, Piece }
// Custom serializable class [Serializable] public class Ingredient { public string name; public int amount = 1; public IngredientUnit unit; }
public class Recipe : MonoBehaviour { public Ingredient potionResult; public Ingredient[] potionIngredients; }
Using a custom PropertyDrawer, every appearance of the Ingredient class in the Inspector can be changed.
Compare the look of the Ingredient properties in the Inspector without and with a custom PropertyDrawer:
Class in the Inspector without (left) and with (right) custom PropertyDrawer.
PropertyDrawer は CustomPropertyDrawer 属性とドローワーを使用する Serializable クラスの型をアタッチします。
using UnityEditor; using UnityEngine;
// IngredientDrawer [CustomPropertyDrawer(typeof(Ingredient))] public class IngredientDrawer : PropertyDrawer { // Draw the property inside the given rect public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) { // Using BeginProperty / EndProperty on the parent property means that // prefab override logic works on the entire property. EditorGUI.BeginProperty(position, label, property);
// Draw label position = EditorGUI.PrefixLabel(position, GUIUtility.GetControlID(FocusType.Passive), label);
// Don't make child fields be indented var indent = EditorGUI.indentLevel; EditorGUI.indentLevel = 0;
// Calculate rects var amountRect = new Rect(position.x, position.y, 30, position.height); var unitRect = new Rect(position.x + 35, position.y, 50, position.height); var nameRect = new Rect(position.x + 90, position.y, position.width - 90, position.height);
// Draw fields - passs GUIContent.none to each so they are drawn without labels EditorGUI.PropertyField(amountRect, property.FindPropertyRelative("amount"), GUIContent.none); EditorGUI.PropertyField(unitRect, property.FindPropertyRelative("unit"), GUIContent.none); EditorGUI.PropertyField(nameRect, property.FindPropertyRelative("name"), GUIContent.none);
// Set indent back to what it was EditorGUI.indentLevel = indent;
EditorGUI.EndProperty(); } }
PropertyDrawer の他の使い方は PropertyAttribute の付いたメンバーの外観を変更することができます。 例えば整数で特定の範囲内で値を設定したい場合に、インスペクターにはスライダーとして表示することができます。 これは RangeAttribute としてビルドインされている PropertyAttribute 機能でこのように使用します。
using UnityEngine; using System.Collections;
public class ExampleClass : MonoBehaviour { // Show this float in the Inspector as a slider between 0 and 10 [Range(0.0F, 10.0F)] public float myFloat = 0.0F; }
PropertyAttribute を作成することもできます。RangeAttribute を実装例として参考にしてください。 この属性は PropertyAttribute クラスを継承する必要があります。必要であればこの属性クラスにパラメーターや変数の値を保持しておくことができます。
// This is not an editor script. The property attribute class should be placed in a regular script file. using UnityEngine;
public class RangeAttribute : PropertyAttribute { public float min; public float max;
public RangeAttribute(float min, float max) { this.min = min; this.max = max; } }
属性を作成したら次は属性を持つプロパティーの描画のために PropertyDrawer を作成する必要があります。 このドローワークラスは PropertyDrawer を継承することと、CustomPropertyDrawer 属性を付ける必要があります。
// The property drawer class should be placed in an editor script, inside a folder called Editor.
// Tell the RangeDrawer that it is a drawer for properties with the RangeAttribute. using UnityEngine; using UnityEditor;
[CustomPropertyDrawer(typeof(RangeAttribute))] public class RangeDrawer : PropertyDrawer { // Draw the property inside the given rect public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) { // First get the attribute since it contains the range for the slider RangeAttribute range = attribute as RangeAttribute;
// Now draw the property as a Slider or an IntSlider based on whether it's a float or integer. if (property.propertyType == SerializedPropertyType.Float) EditorGUI.Slider(position, property, range.min, range.max, label); else if (property.propertyType == SerializedPropertyType.Integer) EditorGUI.IntSlider(position, property, Convert.ToInt32(range.min), Convert.ToInt32(range.max), label); else EditorGUI.LabelField(position, label.text, "Use Range with float or int."); } }
パフォーマンス上の理由から EditorGUILayout クラスは PropertyDrawer を使用できないことに注意してください。
関連項目: PropertyAttribute クラス、CustomPropertyDrawer クラス
attribute | プロパティーの PropertyAttribute を取得します(読み取り専用) |
fieldInfo | このプロパティーが表すメンバーのリフレクション FieldInfo (読み取り専用) |
CanCacheInspectorGUI | Override this method to determine whether the inspector GUI for your property can be cached. |
GetPropertyHeight | ピクセル単位で GUI の高さを設定します そのためにはこのメソッドをオーバーライドしてください |
OnGUI | このメソッドをオーバーライドしてプロパティーに自身の GUI を作成します |