[Unity] Inspector上でVector3の各成分を(0,1)に制限する


Unityでプロパティの範囲を(0,1)に制限しておきたいとき、floatまたはint値であれば

[SerializeField, Range(0f,1f)] float hoge;

のようにすることで値を0から1の間に制限することができます。
Vector2/3で同様に

[SerializeField, Range(0f,1f)] Vector3 hoge;

とすると、Inspector上で Use Range with float or int. と怒られてしまいます。

そこで、下記のスクリプトを用意し、

UserAttribute.cs
using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;
#endif

public class Clamp01VectorAttribute : PropertyAttribute { }

#if UNITY_EDITOR
[CustomPropertyDrawer(typeof(Clamp01VectorAttribute))]
public class Clamp01VectorDrawer : PropertyDrawer
{
    // Necessary since some properties tend to collapse smaller than their content
    public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
    {
        return EditorGUI.GetPropertyHeight(property, label, true);
    }

    // Draw a disabled property field
    public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
    {
        switch (property.type)
        {
            case "Vector2":
                property.vector2Value = new Vector2(
                    Mathf.Clamp01(property.vector2Value.x),
                    Mathf.Clamp01(property.vector2Value.y)
                );
                break;
            case "Vector3":
                property.vector3Value = new Vector3(
                    Mathf.Clamp01(property.vector3Value.x),
                    Mathf.Clamp01(property.vector3Value.y),
                    Mathf.Clamp01(property.vector3Value.z)
                );
                break;
        }
        EditorGUI.PropertyField(position, property, label, true);
    }
}
#endif

これを適当な場所に保存してから

[SerializeField, Clamp01Vector] Vector2 hogeVec = new Vector2(0.5f,1f);

のように記述すると、インスペクター上からは(0,1)の範囲しか入力できなくなります。
(0,1)ではなく(min,max)にするにはこちら

余談ですが、エディター拡張をEditorフォルダ外に置く今回のような方法、いろんな記事でちょこちょこ見ていたので今回自分もやってみたのですが、普通にビルドも通りますね。いまさら?