
プレハブの時だけ表示するSerializeField
こんばんは、しのです。
さて、最近エディタ拡張を作るのにはまっておりまして、表題の通り思ったわけであります。「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を設定します。(これは多言語化のためにHeaderやTooltipを異なる言語で設定したり、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 奈切 しの