背景
こちらの記事で、Vector2をスライダーとして表示する方法が紹介されていました。
これを参考にして作ってみたところ、ビルド時に MinMaxRangeAttribute
が存在しないとエラーが出てしまったので、それの修正録です。
プログラム全文(このままだとビルドエラー)
MinMaxRangeAttribute.cs
using System;
namespace UnityEngine
{
[AttributeUsage(AttributeTargets.Field)]
public sealed class MinMaxRangeAttribute : PropertyAttribute
{
public readonly float min;
public readonly float max;
public MinMaxRangeAttribute(float min, float max)
{
this.min = min;
this.max = max;
}
}
}
MinMaxRange.cs
using UnityEngine;
namespace UnityEditor
{
[CustomPropertyDrawer(typeof(MinMaxRangeAttribute))]
internal sealed class MinMaxRange : PropertyDrawer
{
private const float kPrefixPaddingRight = 2;
private const float kSpacing = 5;
public sealed override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
label = EditorGUI.BeginProperty(position, label, property);
EditorGUI.BeginChangeCheck();
var range = attribute as MinMaxRangeAttribute;
float minValue = property.vector2Value.x;
float maxValue = property.vector2Value.y;
{
Rect labelPosition = new(
position.x,
position.y,
EditorGUIUtility.labelWidth,
position.height
);
EditorGUI.LabelField(labelPosition, label);
}
{
Rect sliderPosition = new(
position.x + EditorGUIUtility.labelWidth + kPrefixPaddingRight + EditorGUIUtility.fieldWidth + kSpacing,
position.y,
position.width - EditorGUIUtility.labelWidth - 2 * (EditorGUIUtility.fieldWidth + kSpacing) - kPrefixPaddingRight,
position.height
);
EditorGUI.MinMaxSlider(sliderPosition, ref minValue, ref maxValue, range.min, range.max);
}
{
Rect minPosition = new(
position.x + EditorGUIUtility.labelWidth + kPrefixPaddingRight,
position.y,
EditorGUIUtility.fieldWidth,
position.height
);
minValue = EditorGUI.FloatField(minPosition, minValue);
}
{
Rect maxPosition = new(
position.xMax - EditorGUIUtility.fieldWidth,
position.y,
EditorGUIUtility.fieldWidth,
position.height
);
maxValue = EditorGUI.FloatField(maxPosition, maxValue);
}
if (EditorGUI.EndChangeCheck())
{
property.vector2Value = new Vector2(minValue, maxValue);
}
EditorGUI.EndProperty();
}
}
}
対応
MinMaxRange.cs
のみEditorフォルダに入れます。
asmdef も含めて、以下のようにしました。
MyRootAssembly.EditorExtension.Private
の方は、Editorのみにして、参照で MyRootAssembly.EditorExtension.Public
を設定します。
C++のヘッダ・ソースみたいな感じで、ちゃんとコンパイルが通ります。
ただし、UnityEditor依存の部分は全てEditorのみのアセンブリに切り離しているので、ビルドエラーが出ることはありません。
他アセンブリから作った属性を使いたいときは、MyRootAssembly.EditorExtension.Public
を参照に設定します。
ファイル構造
EditorExtension/
├╴Private/
│ ├╴Editor/
+ │ │ └╴MinMaxRange.cs
+ │ └╴MyRootAssembly.EditorExtension.Private.asmdef
└╴Public/
+ ├╴MinMaxRangeAttribute.cs
+ └╴MyRootAssembly.EditorExtension.Public.asmdef