テラシュールブログ

旧テラシュールウェアブログUnity記事。主にUnityのTipsやAR・VR、ニコニコ動画についてのメモを残します。

アプリ起動時に指定のメソッドを呼ぶ「RuntimeInitializeOnLoadMethod」に可能性を感じたが錯覚だった気が

追記版

tsubakit1.hateblo.jp

 

Unityはゲームマネージャーを初めとした○○マネージャーを起動時にセットアップする事が出来ない為、多くの場合「○○マネージャーを作るマネージャー」をシーンに配置して、起動時にインスタンス化してもらう、起動用シーンを用意する等々のアプローチが行われてきました。

で、Unity5よりRuntimeInitializeOnLoadMethodが追加され、アプリの起動時にオブジェクト一覧が並べられるようになりました。

RuntimeInitializeOnLoadMethod

RuntimeInitializeOnLoadMethodは、登録したメソッドを持つコンポーネントがシーンに配置されていなくてもアプリ起動時に呼び出されるUnity5の新しい属性(Attribute)です。

この属性を定義したメソッドはシーン上に特に配置しなくともUnityのメインスレッドで呼ばれるらしく、Instantateを用いて必要なオブジェクトを自動的に生成といった処理も起動することが出来ました。

public class SampleCode : MonoBehaviour {

    [RuntimeInitializeOnLoadMethod]
    static void Initialize()
    {
        new GameObject("Instance"typeof(SampleCode) );
    }
}

使用する際の注意

と調子良いこと言っといてなんですが、この手法によるオブジェクトの生成は可能な限り使わないほうが良い気がします。正しくは、アセットとして配布する側は使わない方が良いです。

というのも、この記述が含まれているコードがプロジェクト内にあると、問答無用でインスタンスが生成されてしまいます。ゲームの基本仕様として組み込むならば便利機能なのですが、コードを入れただけで見に覚えのないオブジェクトが生成されては困ります。

もし、特にシーンに何も無いのに勝手にオブジェクトが作られたら、この機能を疑うべきです。下は本当に何もない空のシーンを起動した際のHierarchyです。余計なものが次々と生成されます。

もし自前のアセットに組み込むならば、scripting define symbols 等で 定義しなければ動かない等ノセーフティを用意するのが良さそうです。

f:id:tsubaki_t1:20150322225625g:plain

また、この処理が呼ばれるのはシーンに事前に配置したコンポーネントのAwakeやOnEnableの後(Startの前)です。そのため、シングルトンなオブジェクトに対してこの手法を採用する場合、Awakeでは呼ぶのは早過ぎるかもしれません。

f:id:tsubaki_t1:20150322225156p:plain

さらに言えば、staticなSerializeFieldやpublicなフィールドはシリアライズされないため、Inspectorビューで設定を行う事は出来ません。なのでResourcesにプレハブとして配置するか、コードでセットアップする必要があります。

 

qiita.com