tsugaru’s blog

主に技術的なことをつぶやきます。プログラミング,ポケモンGO,音楽,アニメ等

Unity MonoBehaviourのコンストラクタとPrefabの関係

Object.Instantiateについて色々調べていた。 ここで、生成元のObject originalについて、インスタンス化される前のPrefabのGameObjectを指定できるのに違和感を覚えた。 というよりは、[SerializedField] GameObject prefab;の違和感である。 プレファブが実態となっていないのに、GameObject型のインスタンス変数としてプレファブを指定できるのは、どういうことだとなったわけだ。

そこで、Monobehaviourでは、インスタンス化はAddComponentによって行う、という点を思い出し、コンストラクタを加えてみた。

using UnityEngine;

public class PrefabTest : MonoBehaviour
{
    static int num = 0;
    PrefabTest()
    {
        Debug.Log("Constructor:" + num);
    }

    private void Awake()
    {
        num++;
        Debug.Log("Awake:" + num);
    }
    void Start()
    {
        Debug.Log("Start:"+num);
    }

}

これをつけたオブジェクトをプレファブにしてシーンから取り除く。 その後、シーン上のスクリプトでプレファブへの参照をインスペクタービューで登録した瞬間(エディタの使用中) Constructor:0と表示された。 また、再生を押すと、Instantiateが使われていないのに、Constructor:0と表示された。

これらから、Unityにおいて、GameObjectのインスタンス化は、エディタ上でも、実行中でも、シーンからの参照があった時点で行われることがわかった。 また、インスタンス化されても実際にシーンに設置されないことがある(Awakeなどが呼ばれない)(これはプレファブの参照元ぐらいしかなさそうだが)ということがわかった。つまり、Unityにおける「GameObjectのインスタンス化」と実際の「GameObjectクラスからインスタンスが作成」されるのでは、微妙に意味が異なることがわかった。