[Unity] どのシーンから再生しても必ず実行するスクリプトの書き方
最近になってUnityでのゲーム開発を再開し始めました。
再開と言っても以前に作成していたプロジェクトは完成図も方向性もあいまいなままスタートした状態だったので、それは破棄し新規プロジェクトでの作成に当たっています。
まあ、そもそも3,4年前ぐらいに作ったプロジェクトなので中身を覚えてないですし、使用しているUnityのバージョンも2018と古いものだったので、今から手を入れるには環境がちょっと……という理由もありますね。
昔話はさておき、今回の目的としては「どのシーンから再生しても必ず実行するスクリプトの書き方」になります。
注意点としては数ある方法の一つに過ぎないので、参考程度でお願いします。
検証環境
今回検証したUnityのバージョンは2022.3.29f1になります、この記事を執筆した現在で一番最新のLTSバージョンになりますね。
また、よくある「DontDestroyOnLoad」は使わない方法になります。
Unityではド定番のシーン間を跨いでもオブジェクトを破棄させないために使う関数ですが、軽く調べた限りだと現在ではこの関数の使用は非推奨という記載が多く見受けられたので、別視点でのアプローチになります。
ただ公式サイトの2022.3.29f1のバージョンでのドキュメントではこの関数が非推奨である旨の記載を見つけられなかったので、真偽の程についてはここでは深く掘り下げないでおきます。
RuntimeInitializeOnLoadMethod
早速結論ですが、RuntimeInitializeOnLoadMethodというAttributeを使います。
Attributeは日本語で「属性」という意味になりますが、C#に馴染みのある方はすぐにピンとくるかも知れません。
そうでなくても、UnityでC#スクリプトを書いているのであれば一度は書いたり見たことがあると思います、属性の代表例としては以下のスクリプトになりますね。
[SerializeField]
private string text;
[]で囲まれている部分の記載が属性になります、この場合string型のtext変数をインスペクター上に表示させたい場合に使うSerializeField属性です。
属性とはこの様にクラスやメンバー変数に対して使用する追加情報を与えるためのC#の記法になります、ちなみにC#以外でもJavaとかにも属性は存在します。
で、今回使用する属性が[RuntimeInitializeOnLoadMethod]になります、こちらはメソッドに対して追加情報を与えるのでメソッドの定義の上に書いてあげます。
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
private static void Initialize()
{
Debug.Log("必ず呼ばれるメソッドになる");
}
RuntimeInitializeOnLoadMethodではその後に続く括弧の中で、任意の起動タイミングを指定できます。
上に記載の例の場合だと再生を開始したシーンよりも先にこのメソッドが呼ばれる形になります、他にもRuntimeInitializeLoadTypeには種類があるので自身のスクリプトをどのタイミングで呼びたいかを検討して決めるのが良いと思います。
ちなみにRuntimeInitializeOnLoadMethodを使用する場合、そのクラスはMonoBehaviourは継承しなくても動作します。
「え?でもMonoBehaviourを継承しないとコンポーネントとしてアタッチできないじゃん」と思うかも知れませんが、実はRuntimeInitializeOnLoadMethodは動きがかなり特殊で、スクリプトが存在しているだけで勝手にUnity側で実行してくれます。
なので他のスクリプトから呼ぶ必要もないです、C#スクリプトとしてAssets配下のフォルダに置いておけばそれだけで実行されます。
逆を返せばこのスクリプトは参照という形が全く無い孤立したスクリプトになるので、「どこにも参照はないのに勝手に実行される……」なんて事態になるかもしれません。
個人開発ならそのスクリプトを作るのは自分なので覚えておけばいいですが、チーム開発なんかでは起こりそうなシチュエーションなので、開発に置けるルール整備はしっかりと取り決めを行った上で使うのが吉でしょう。