【Unity】【エディタ拡張】カスタムアトリビュート用コードテンプレート

f:id:halya_11:20180308202930p:plain

自分用メモ。 随時更新。

ソースコード

using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;
#endif

public class AttributeTemplate : MonoBehaviour {
    
    [Sample(2, 30)]
    public int testInt;

    [Sample(0.2f, 20.5f)]
    public float testFloat;
}

[System.AttributeUsage(System.AttributeTargets.Field | System.AttributeTargets.Property, AllowMultiple = false)]
public class SampleAttribute : PropertyAttribute {
    
    public float min;
    public float max;
    
    public SampleAttribute(int min, int max)
    {
        this.min = min;
        this.max = max;
    }

    public SampleAttribute(float min, float max)
    {
        this.min = min;
        this.max = max;
    }
}

#if UNITY_EDITOR
[CustomPropertyDrawer(typeof(SampleAttribute))]
public class SomeAttributeDrawer : PropertyDrawer
{
    // GUIが描画されるときに呼ばれる
    // リストの場合は要素一つ一つが描画されるときに呼ばれる
    public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
    {
        var attr = attribute as SampleAttribute;

        // GUILayoutではなくGUIで描画する
        EditorGUI.PropertyField(position, property, label, true);
        EditorGUI.indentLevel++;
        position.y += EditorGUI.GetPropertyHeight(property);
        EditorGUI.LabelField(position, attr.min + "~" + attr.max + "で制限中");

        // Attributeに定義したフィールドの値を使ってクランプ
        if (property.propertyType == SerializedPropertyType.Integer) {
            property.intValue = Mathf.Clamp(property.intValue, (int)attr.min, (int)attr.max);
        }
        if (property.propertyType == SerializedPropertyType.Float) {
            property.floatValue = Mathf.Clamp(property.floatValue, attr.min, attr.max);
        }
    }
    
    // プロパティ描画領域の高さを取得するために呼ばれる
    public override float GetPropertyHeight (SerializedProperty property, GUIContent label)
    {
        // デフォルトの高さを返す場合はこのように書く
        return EditorGUI.GetPropertyHeight(property) * 2;
    }
}

#endif

結果

f:id:halya_11:20180308202930p:plain