Unityでちょっとした初期化などを事前に行う
インスペクタから変更できないSerializeを行う。
Monobehaviorを継承したクラスで、[SerializeField]アトリビュートをつけると、シリアライズできるのは良いのですが、 初めに参照を設定したら後はインスペクタから変更できないようにしておきたい場合もあると思います。 そんな時の対処法の一つです。
void Awake()より早く設定できることや、実行時に(極小ですが)GetConponentしない分有利です。(当然かわりにシリアライズ分のデータはかかるとして)
方針
- [SerializeField,HideInspector]アトリビュートでシリアライズできるけどインスペクタからは見えないメンバをつくっておく。
- void Reset()によってアタッチした瞬間に参照関係を設定
- おまけにvoid Awake()に一応Assertを入れてあげる
まずはコード
たとえば同オブジェクトにアタッチされたカメラを取得するなら次のようなコードになります。
using UnityEngine; public class CameraController : MonoBehaviour { [SerializeField,HideInInspector] Camera camera_; void Reset () { camera_ = this.GetComponent<Camera>(); } void Awake () { Debug.Assert(camera_ != null); } //以下適当なコード }
ちなみにアタッチするとこんな感じになります。
[SerializeField]や[HideInspector]について
アトリビュート全般に関してはテラシュールブログ様がとてもわかりやすい記事をくださっています。 ここで重要なのは
- [SerializeField]でメンバはシリアライズできる
- [HideInspector]でメンバはインスペクタ上からは見えなくなる
以上の二点です。
void Reset()について
公式のリファレンスに素晴らしく簡潔にわかりやすく記述してくださっています。 ここで重要なのは
- void Reset()はエディタ上でスクリプトをオブジェクトにアタッチした際に呼ばれる。
という一点です。
Assertについて
void Awake()内にAssertを書くことで、万が一うまくシリアライズできていない場合にエラーを出してわかるようにしておきます。 Assertは引数がfalseになるとエラーを出してくれて、かつリリース時にはコンパイルされません。(つまりデバッグ中だけ動作する。)
応用について
これを応用して簡易的に事前に計算できるものは事前に計算したりすることが可能です。
とても初歩的かつ地味な内容でしたが、お読みいただきありがとうございました。