今回はUnityのスクリプトでAttribute(属性)を付けてインスペクタをカスタマイズしてみたいと思います。
今回の場合は拡張を使ったカスタマイズではなくAttributeを取りつけてインスペクタに変化を加えるという感じになります。
Attribute(属性)を付けて変化を与える
クラスやフィールド、フィールドの間にAttribute(属性)を付ける事で項目の表示に変化を加える事が出来るようになります。
C#の場合は取りつけるべきアトリビュートを[アトリビュート]で囲いますが、JavaScriptの場合は @アトリビュート という形式になります。
JavaScriptでは一部違う表記が必要になる事もあるのでそのまま変えるだけで動作しない場合もあります。
クラスに取り付けるAttribute
クラスに取り付けるAttributeについて見ていきます。
RequireComponent
RequireComponentはこのスクリプトをゲームオブジェクトに取り付けた時に必要な他のコンポーネントも取りつけるようになります。
例えばキャラクターの移動をRigidbodyを使用して動かしていた場合はスクリプトに加えてRigidbodyが必要です。
そんな時にこのアトリビュートを付けておけばスクリプトと一緒にRigidbodyが取り付けられます。
AddComponentMenu
インスペクタのAdd Componentボタンを押した時のメニューにこのスクリプトを追加します。
DisallowMultipleComponent
この属性を取りつけると同じコンポーネントを同じゲームオブジェクトに複数取りつける事が出来なくなります。
ExecuteInEditMode
この属性が設定されているとプレイモード以外でもコールバック関数(UpdateやOnGUI)が呼ばれるようになります。
インスペクタでなんらかの値の変更やメニュー項目の選択等を行うとUpdateやOnGUIが呼ばれるので、Updateメソッド内にフィールド値をコンソールに出力するような処理を書いていれば、
Unityをプレイモードにしていなくてもコンソールに値が表示されるようになります。
HelpURL
この属性を指定して値を設定すると
↑のヘルプアイコンをクリックした時にそのURLのページを開く事が出来るようになります。
フィールドに取り付けるAttribute
フィールドに取り付けるAttributeについて見ていきます。
Multiline
Multilineはインスペクタで複数行のテキストフィールドを使う場合に使用します。
引数で行数を指定する事が出来ます。
TextArea
TextAreaはインスペクタでテキストエリアとして表示します。
Multilineとの違いは行数が制限値より大きくなった場合スクロールバーが表示されるようになるところです。
引数には最初表示する行数とスクロールバーの表示開始行数を指定する事が出来ます。
HideInspector
HideInspectorはインスペクタにこのフィールドを表示しないようにします。
Range
Rangeは指定範囲内で値を制御する事が出来、インスペクタではスライダーで値を変更する事が出来るようになります。
Delayed
この属性を付けたint型、float型のフィールドは値の変更が遅れます。
例えば通常のint型のフィールド値であればUnityを実行中にインスペクタで値を変更すれば即座にその値が適用されますが、Delayedを付けたフィールドは
インスペクタで値を書き換えた後にEnterキーを押して確定しないと値が適用されません。
またEnterを押す前にフォーカスを外すと値が元の値に戻ります。
ColorUsage
ColorUsageは色の設定でアルファ値を使わないようにする事が出来ます。
SerializeField
SerializeFieldアトリビュートをフィールドに付けるとそのフィールドをシリアライズ化可能にします。
ネットワークを介してデータを送受信したりファイルにデータとして保存する時はこのSerializeFieldを取りつけるといいかもしれません。
Tooltip
インスペクタの項目上にマウスカーソルが来た時に項目の説明等を表示する時に使用します。
ContextMenuItem
インスペクタの項目上で右クリックした時に自前のメニューを表示するようにします。
メニューを選択した時に何らかの処理を実行させる事が出来ます。
メソッドに取り付けるAttribute
ContextMenu
インスペクタのコンポーネントのタイトル上で右クリックした時やコンポーネント右上の歯車を押した時に表示されるコンテキストメニューに自前のメニューを追加します。
メニューを選択した時に実行するメソッドを設定しておき自前の処理を行わせる事が出来ます。
RuntimeInitializeOnLoadMethod
クラスメソッドに付けるとクラスメソッドの初期化等が行えます。
引数にLoadTypeを指定するとタイミングを変更する事が出来、
RuntimeInitializeLoadType.BeforeSceneLoadでシーンが読み込まれる前
RuntimeInitializeLoadType.AfterSceneLoadでシーンが読み込まれた後
になります。
BeforeSceneLoadだとAwakeが実行されるまえに呼び出され、AfterSceneLoadだとAwakeの後に実行されます。
フィールド間に取り付けるAttribute
Space
Spaceはインスペクタの間にスペースを入れます。
引数に数値を指定するとそのピクセル値分のスペースが空きます。
Header
インスペクタにこの項目の説明等の文字列を表示したい時に使用します。
アトリビュートを設定し確認してみる
それではサンプルスクリプトを作成し確認してみましょう。
スクリプト名はInspectorValue2としています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 | using UnityEngine; using System.Collections; // このスクリプトを取りつけた場合に必ずCharacterControllerが一緒に取り付けられる [RequireComponent(typeof(CharacterController))] // AddComponentのメニューに追加する [AddComponentMenu("InspectorTest/MyTest")] // 同一ゲームオブジェクトに複数設定する事が出来なくなる [DisallowMultipleComponent] // プレイモード以外でもコールバック関数が呼ばれる [ExecuteInEditMode] // ヘルプURLの設定 [HelpURL("https://gametukurikata.com/")] public class InspectorValue2 : MonoBehaviour { // 複数行のテキストフィールドになる [Multiline(5)] public string stringValue1; // テキストエリアになる [TextArea(2, 5)] public string stringValue2; // インスペクタには表示しない [HideInInspector] public bool boolValue; // スペースを50ピクセル分入れる [Space(50)] // int型の範囲設定 [Range(0, 50)] public int intValue; // float型の範囲設定 [Range(-10f, 10f)] public float floatValue1; // 値の変更を遅らす [Delayed] public float floatValue2; // アルファ値を利用しない [ColorUsage(false)] public Color color; // シリアライズ化可能にする [SerializeField] int serializeField; // インスペクタに文字列を表示 [Header("インスペクタにこの項目の説明等の文字列を表示する")] // ツールチップを表示 [Tooltip("マウスが項目上に来た時に項目説明の表示")] public Gradient gradient; // コンテキストメニューの追加 [ContextMenu("WriteConsole")] void WriteConsole() { Debug.Log ("コンテキストメニューを選択した時に実行"); } // コンテキストにメニューアイテムを追加 [ContextMenuItem("ResetTestField", "ResetField")] public string test = "Default Text"; public void ResetField() { test = ""; } void Awake() { Debug.Log ("Awake"); } [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)] static void InitializeTest() { Debug.Log ("InitializeTest"); } void Update() { Debug.Log (floatValue2); } } |
紹介したAttributeを全て詰め込んでスクリプトを作成しました。
Headerのアトリビュートまでを確認します。
↑のようにインスペクタで表示され色々確認してみました。
RuntimeInitializeOnLoadMethodの影響でスクリプトを設定せずともInitializeTestメソッドが実行されています。
ゲームオブジェクトにスクリプトを設定するとRequireComponentの影響で一緒にCharacterControllerが設定されています。
その他もさきほど紹介した内容通りになっている事がわかると思います。
次にToolTipとContextMenuItem、ContextMenu、AddComponentMenu、DisallowMultipleComponentのアトリビュートの確認です。
↑のような感じになりました。
AddComponentMenuの設定でInspectorTest/MyTestとしてしまったのでMyTestを選択するとInspectorValue2(今回のスクリプト)が設定されることになります。
本来であればInspectorTest/InspectorValue2等とスクリプト名を設定するべきでしたね・・・・(^_^;)
終わりに
Attributeを付ける事によってインスペクタの表示を変える事が出来ました。
今回のようにアトリビュートを取りつけるだけで変化させる事も出来ますが、エディター拡張をしてもっと便利に開発を進めるようにする事も出来ますね。
それはまた別の機会に。