PropertyDrawerでインスペクタ上の見た目を変更する

Unityでは選択したオブジェクトに含まれるコンポーネントの情報を、インスペクタに表示して編集することができます。

エディタ拡張用のスクリプトを用意することで、コンポーネント単位でのインスペクタ上の見た目を変更し、編集しやすくすることもできます。

複数のコンポーネントで使用される特定の型の見た目を変更するには、PropertyDrawerを使用します。

PropertyDrawerとは?

PropertyDrawerは、Unityのインスペクタ上で特定のプロパティの表示をカスタマイズするための仕組みです。

PropertyDrawerを使用することで、以下のことが可能になります。

  • 特定のフィールドの表示方法を変更
  • 複雑なデータ構造を分かりやすく表示

PropertyDrawerUnityEditor名前空間に含まれるエディタ拡張機能で、以下の2つの方法で利用できます。

  1. 属性ベース:カスタム属性と紐付けて、属性を付けたフィールドのみに適用
  2. 型ベース:特定の型(SpriteColorなど)と紐付けて、その型を使うすべてのフィールドに適用

主なメソッド:

  • OnGUI:インスペクタでの描画処理を記述します
  • GetPropertyHeight:プロパティの表示高さを指定します

PropertyDrawerSerializedPropertyを通じてデータにアクセスするため、

Unityのシリアライズシステムと統合されており、Undo/Redo機能も自動的に対応します。

AttributeとPropertyDrawerを紐付ける

以下のようなAttributeクラスを用意します。

using UnityEngine;

public class ReadonlyAttribute : PropertyAttribute
{
}

次に、以下のPropertyDrawerクラスを用意します。

このクラスは、UnityEditor上でしか使用できないためEditorフォルダ以下に配置します。

逆にAttributeクラスはEditorフォルダ外に配置します。

using UnityEditor;
using UnityEngine;

[CustomPropertyDrawer(typeof(ReadonlyAttribute))]
public class ReadonlyPropertyDrawer : PropertyDrawer
{
    override public void OnGUI(Rect position, SerializedProperty property, GUIContent label)
    {
        GUI.enabled = false;
        EditorGUI.PropertyField(position, property, label);
        GUI.enabled = true;
    }
}

以下のような適当なコンポーネントクラスを用意しました。

_int2だけ、Readonly属性を追加してあります。

using UnityEngine;

public class PropertyDrawerTest : MonoBehaviour
{
    [SerializeField] private int _int1 = 100;
    
    [SerializeField, Readonly] private int _int2 = 200;
}

これを適当なオブジェクトに追加すると、インスペクタ上では以下のような見た目になります。

ReadonlyPropertyDrawerによって描画されるようになったので、_int2は編集できなくなりました。

特定の型と紐付ける

今度はAttributeを用意せず、以下のPropertyDrawerだけ用意しました。

これもEditorフォルダ以下に配置します。

実装内容としては、表示する高さを4倍にしています。

using UnityEditor;
using UnityEngine;

[CustomPropertyDrawer(typeof(Sprite))]
public class CustomSpritePropertyDrawer : PropertyDrawer
{
    public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
    {
        return base.GetPropertyHeight(property, label) * 4f;
    }
    
    public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
    {
        property.objectReferenceValue = EditorGUI.ObjectField(position, label, property.objectReferenceValue, typeof(Sprite), false);
    }
}

以下のようにインスペクタ上にSpriteを編集できるように追加しました。

Attributeは指定していません。

using UnityEngine;

public class PropertyDrawerTest : MonoBehaviour
{
    [SerializeField] private int _int1 = 100;
    
    [SerializeField, Readonly] private int _int2 = 200;
    
    [SerializeField] private Sprite _sprite1;
    [SerializeField] private Sprite _sprite2;
}

デフォルトでは以下のようになります。

CustomSpritePropertyDrawerがある場合は以下のようになります。

Spriteが確認しやすくなりました。

Sprite型に対応したPropertyDrawerなので、既存のコンポーネント(例えばImageコンポーネントなど)にも影響を与えます。

まとめ

今回はPropertyDrawerについて解説しました。

PropertyDrawerを使用することで、インスペクタ上の一部のプロパティの見た目を変更することができます。

Attributeを用意すればAttributeを指定されたフィールドにのみ影響するようになりますが、

型を指定した場合はその型を使用している箇所全体に影響が出るようになります。

コンポーネント毎のCustomEditorを用意しなくても個々のプロパティの見た目を変え、編集しやすくなるので、

エディタ拡張に慣れたら是非挑戦してみてください。

📣おしらせ!

Unity Asset Storeで GROW YOUR GARDEN セール が開催中です。

農業関係のアセットなどが最大50%OFFでセール中です。

🔗関連ページ