見出し画像

Unity「プレハブの時だけインスペクタに表示したいよ」って記事です。

 こんばんは、しのです。
 さて、最近エディタ拡張を作るのにはまっておりまして、表題の通り思ったわけであります。「SerializeFieldって便利だけどインスペクタごちゃつくし、プレハブの設定の時しか触らないんだよなぁ….。」って。

 てことで、今回、「インスペクターにプレハブの時だけシリアライズする拡張機能」について。記録を残そうと思います!誰かの役に立つことを願って。

通常のSerializeFieldの場合

回転するスクリプト


 これはただただ回転するだけのスクリプトです。変数としては、「rotate_speed」がSerializeFieldでインスペクターに表示されているはずです。

通常のインスペクター


 ただアタッチしただけなので通常のインスペクターの表示です。ごくごく普通。

これをプレハブの時だけ表示するようにします。


エディタ拡張+SerializeFieldの場合

左:オブジェクト時|右:プレハブ編集時

 本拡張機能を使うとこういうことができます。
・スプライトを複数登録してenumで選択したい。
・UIの切り替え画像を登録がたくさんある。プレハブ生成時に触りたいパラメーターはTextだけ。 ….等々。


どうやって実装するの?

 ひとまず実装のコードをお見せします。

アトリビュート
ドロワー

 使用するのはPropertyAttributeとPropertyDrawerクラスです。それぞれ、以下の用途で使用します。

Attribute:
「フィールドやプロパティに特別な動作や表示を追加するためのクラス 」
・カスタム属性を作成する際の基底クラスとして使用される
・フィールドやプロパティに適用され、そのメタデータを定義する
・単独では機能せず、対応するPropertyDrawerと組み合わせて使用する

Property:
「Attributeのフィールドやプロパティの描画方法を定義するクラス」
・カスタムエディタUIを作成するための基底クラス
・インスペクタでの表示方法をカスタマイズ
・特定のPropertyAttributeに対応するように設計される

クラスの説明(Drawer編)

 また、今回の拡張は単純な構造のため、Attributeの特別な操作は不要なため、Drawer(描画側)のみの実装となります。
それぞれの関数について順に説明します。
OnGUI
GetPropertyHeight
IsEditorMode

①OnGUI
全体の描画を行います。
受け取ったプロパティ(Serializeされたもの)をIsEditorMode関数の結果がtrueであれば描画をします。

②GetPropertyHeight
IsEditorMode関数の結果がtrueであればデフォルトの高さを取得して戻り値として返します。falseであれば高さを0として返します。

③IsEditorMode
プロパティのシリアライズされたオブジェクトを取得します。
その後、現在プレハブの編集画面にいるか、そのオブジェクトがプレハブの一部であるかどうかを判定し、真偽を返します。

③の結果をもとに、描画するか、高さを作るかを決定しています。

クラスの説明(Attribute編)

 アトリビュートの各要素について説明します。

アトリビュートの構成として、カスタム属性の使用方法を定義するメタ要素である「AttributeUsage」で指定します。

以下、設定が必要な項目を順に説明していきます。
AttributeTargets
Inherited
AllowMultiple

AttributeTargets・・・属性の影響範囲を決めます。今回はSerializeFieldの要素を隠したいので、Field(変数、構造体)を設定します。

Inherited・・・派生クラスへも影響を与えるかどうか。今回特に制限などはつける必要性がないため、trueを設定します。

AllowMultiple・・・同じ要素に複数回属性をつけれるかを決めます。これはシリアライズを隠すか否かだけなので、falseを設定します。(これは多言語化のためにHeaderTooltipを異なる言語で設定したり、EventHandlerを複数種類登録するときにtrueに設定します。)


さいごに

 ここまで実装が完了したら、あとはSerializeFieldと併用することでプレハブ限定のシリアライズフィールドが使用できます。以下、記述例となります。ぜひ参考に使用してみてください。

記述例:
[SerializeField, PrefabInspector] private int hoge;
[Serializable]
struct UserData
{
   public string name;
   public int age;
   public int height;
};
[SerializeField, PrefabInspector] private UserData data;

最後までご覧いただきありがとうございました!
皆様のUnity開発にちょっぴりの幸せがありますよう。
それではまた。

2024/10/25 奈切 しの

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