見出し画像

【Unity】インスペクターにボタンを表示するカスタムアトリビュートを作ってみた

最近インスペクターのカスタマイズが出来るようになったのですが、「このスクリプトにちょっとボタンが欲しい」という時に、ボタン一つのために毎回インスペクターのカスタマイズをするのは大変です。

Unityでは変数の宣言の上に、[Range(1, 6)]や[Header("title")]のように、アトリビュートを付けることでインスペクターの表示をカスタマイズできます。アトリビュートは元から用意されているものもありますが、自作することも可能です。

そこで、インスペクターにボタンを表示するカスタムアトリビュートを作ってみました。これを使えばわざわざカスタムインスペクターを書かなくても、一行追加するだけでボタンを追加できます。

   [Button("Test1")]
   public bool foo;

画像3

カスタムアトリビュートのコード

↓ 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のインスペクターでの表示は下のようになります。

画像1

Test1ボタンを押すと Test1()が実行され、A + Bボタンを押すとTest2()が実行されます。

画像2



この記事が気に入ったらサポートをしてみませんか?