はじめに
いきなりですが、Unityにエントリーポイントは存在していません。
たとえば、C言語のmain関数などです。
Unityでは各オブジェクトのAwake関数が先に呼ばれるため、そこで初期化処理を行うことが多いのではないでしょうか?
ですが、複数オブジェクトがある場合Awakeの呼び出し順が制御できないということが発生します。
なので、エントリーポイントに相当するものを、自前で用意していきましょう。
Awakeのみの場合
using UnityEngine;
public class GameManager : MonoBehaviour
{
void Awake()
{
Debug.Log("最初に呼び出される");
}
}
MonoBehaviourのオブジェクトでエントリーポイントを手軽に作りたい場合は上記のようになります。
きちんとルールを固めれば、これでも問題はないでしょう。
ですが、Awakeの呼び出し順を考える必要があり、少々不安が残ります。
RuntimeInitializeOnLoadMethodを使用する
using UnityEngine;
public class GameManager
{
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
private static void OnBeforeSceneLoad()
{
Debug.Log("最初に呼び出される");
}
}
RuntimeInitializeOnLoadMethod属性を付けることで、メソッドが呼ばれるタイミングを制御できます。
BeforeSceneLoadを指定すると、Awakeよりも前に実行されます。
しかし、これだと初期化時に必要なプレハブなどのアセットをシリアライズできないので少々不便です。
シリアライズ可能にする
using UnityEngine;
public class GameManager : MonoBehaviour
{
public GameObject hogePrefab;
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
private static void OnBeforeSceneLoad()
{
Debug.Log("最初に呼び出される");
}
void Awake()
{
Debug.Log("OnBeforeSceneLoadの実行後に呼び出される");
}
}
MonoBehaviourを継承することで、必要なアセットやオブジェクトをシリアライズし、参照できます。
また、Awakeなどのイベント関数も使用できます。
おわりに
これでUnity上でエントリーポイントを用意することができました。
余計な不具合を出さない、また可読性を高めるためにもなるべくRuntimeInitializeOnLoadMethodを使用したほうが良さそうです。
参考