【Unity】インスペクターにボタンを表示するカスタムアトリビュートを作ってみた
最近インスペクターのカスタマイズが出来るようになったのですが、「このスクリプトにちょっとボタンが欲しい」という時に、ボタン一つのために毎回インスペクターのカスタマイズをするのは大変です。
Unityでは変数の宣言の上に、[Range(1, 6)]や[Header("title")]のように、アトリビュートを付けることでインスペクターの表示をカスタマイズできます。アトリビュートは元から用意されているものもありますが、自作することも可能です。
そこで、インスペクターにボタンを表示するカスタムアトリビュートを作ってみました。これを使えばわざわざカスタムインスペクターを書かなくても、一行追加するだけでボタンを追加できます。
[Button("Test1")]
public bool foo;
カスタムアトリビュートのコード
↓ CustomAttributes.cs
アトリビュートの定義。Editorフォルダ以外に入れる
using UnityEngine;
public class ButtonAttribute : PropertyAttribute
{
public string methodName;
public string buttonName;
public ButtonAttribute(string methodName, string buttonName = null)
{
this.methodName = methodName;
if (buttonName == null)
{
this.buttonName = methodName;
}
else
{
this.buttonName = buttonName;
}
}
}
↓ ButtonDrawer.cs
アトリビュートの描画。Editorフォルダに入れる
using System.Reflection;
using UnityEngine;
using UnityEditor;
[CustomPropertyDrawer(typeof(ButtonAttribute))]
public class ButtonDrawer : PropertyDrawer
{
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
ButtonAttribute buttonAttribute = (ButtonAttribute)attribute;
// プロパティ名のラベルを描画し、ラベル以外のrectを返す
Rect rect_content = EditorGUI.PrefixLabel(position, label);
// ボタンを描画
if (GUI.Button(rect_content, buttonAttribute.buttonName))
{
try
{
// メソッド名からメソッドを取得、実行
MethodInfo method = property.serializedObject.targetObject.GetType().GetMethod(buttonAttribute.methodName);
method.Invoke(property.serializedObject.targetObject, null);
}
catch
{
Debug.Log(buttonAttribute.methodName + " を実行できません");
}
}
}
}
↓ ButtonTest.cs
サンプルのスクリプト。 [ButtonAttribute("Test1")]を変数の上につけると、ボタンを表示する。(元の変数は表示されないので何でも良い)
・第一引数の"Test1"が実行するファイル名
・第二引数の "A+B"はボタンに表示する名前(省略可)
using UnityEngine;
public class ButtonTest : MonoBehaviour
{
[Button("Test1")]
public bool foo;
[Button("Test2", "A+B")]
public bool bar;
public int A;
public int B;
public void Test1()
{
Debug.Log("Test");
}
public void Test2()
{
Debug.Log("A+B = " + (A + B).ToString());
}
}
実行結果
ButtonTestのインスペクターでの表示は下のようになります。
Test1ボタンを押すと Test1()が実行され、A + Bボタンを押すとTest2()が実行されます。