前回まででインスペクタに独自UIの入力フォームができました。
入力した値は保存しなければなりません。じゃなきゃ、なんのために苦労して描画したんだって話です。
SerializedProperty でのデータのやりとり
PropertyDrawerでオーバーライドしたOnGUI関数にSerializedProperty 型の引数がありますね。 フォームの入力値を渡すには、これを介して操作しなければなりません。
例えばMonoBehaviourで下記のようにAttributeを設定した場合、
[MyValue] public float TestValue;
TestValueに設定済みの数値を取得するには、
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) { float currentValue = property.floatValue;
として取得します。
OnGUI内では、TestValue という変数を使うのではなく、名前はわからないけどfloat型の数値とやりとりするよということをぼんやりと教えてやる必要があるのです。
逆にEditorGUIで入力された値を設定するには、
property.floatValue = value;
として設定してやります。
なので float型を入力させるフォームは
float currentValue = property.floatValue; // float値入力のテキストボックス float value = EditorGUI.FloatField( new Rect( EditorGUIUtility.labelWidth, position.y, position.width - EditorGUIUtility.labelWidth, EditorGUIUtility.singleLineHeight ), currentValue // 現在の値 ); property.floatValue = value; // 入力値を設定
と書けば完成です。
Attributeに引数を持たせる
例えば最大値と最小値を定義してやりたいとき、
Attributeには引数として固定値を設定することができます。
[MyValue(1, 10)] public float TestValue;
これを受け取るには、Attributeクラスでコンストラクタを定義します。
public class MyValueAttribute : PropertyAttribute { public float MaxValue; public float MinValue; public MyValueAttribute (float min, float max) { MaxValue = max; MinValue = min; } }
さらにPropertyDrawerには attribute というメンバ変数があらかじめ定義されており、OnGUI関数内で
MyValueAttribute attr = attribute as MyValueAttribute;
としてキャストしてやれば、MaxValue、MinValueにアクセスできます。
んん、ややこしい!
三回にもわけてPropertyDrawerについて書くとは思ってもみなかったわけですが、まあ書いてあらためて、ちょっと難しすぎるんじゃないかと思った次第です。
一回目の冒頭で書いたとおり、エディタ拡張は大事な機能なので、ぜひマスターしたいところです。