テラシュールブログ

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

Resourcesから非同期でインスタンス化する

Unity 2018系はこちら

tsubakit1.hateblo.jp

 

---

 

Unity 4.5.3よりResources.LoadAsyncが追加されました。これは今までResources.Load時に停止させていた時間を停止させず、非同期でロードする命令です。

しかし、実際にコレを扱ってみて失望するかもしれません。理由は簡単で、非同期で読んでいるハズなのに停止するからです。

f:id:tsubaki_t1:20140821003321g:plain

 

非同期で読んでいるハズなのに固まってしまう。答えは簡単です、こういった停止の概ねの原因はResources.Loadでは無いからです。

この謎を知るため、プレハブをインスタンス化する際、以下のコードを使用してみます。

 

擬似非同期の読込

 

これは一括でインスタンス化するのではなく、順次インスタンス化を進めていくスクリプトを内包したものです。

これを利用してインスタンス化すると、ほぼ停止無くオブジェクトをインスタンス化する事が可能です。

 

f:id:tsubaki_t1:20140821004515g:plain

 

さて、この動作ですが、2回目以降は物凄く高速に処理されます。では結局何が重いのかと言えば、実際はテクスチャ*1。やオーディオ、それとシェーダーのコンパイル*2に負荷がかかっています。*3

 

これに対抗するため、事前にテクスチャやシェーダーを逐次インスタンス化・メモリに登録しておき、実行することでこのスパイクを大幅に軽減する案があります。

しかし、実際マテリアルをシーンに置く場合、Resourcesのようにランタイムでインスタンスを呼び出す意味が無くなります。


 

とは言え、ランタイムに構築する方法は正直面倒臭いです。それを回避するために今NestedPrefab3*4を作ってたりしますが、まあまあ。

 

 ちなみにテクスチャの非同期ロードはUnity 5.3で追加されました。また、シェーダーはPreloadに設定しておけば事前にロードが出来るようになっています。

tsubakit1.hateblo.jp

*1:GL_Texture化はメインスレッドで行われます。一応はネイティブプラグインにて自前でGL_Textureを作りUnityへ登録する事も可能です。バックグラウンドでテクスチャの読込が本当に可能なら非同期ロードも可能かもしれません

*2:OpenGLESは実行時にシェーダーをコンパイルするそうです

*3:これに関しては、今後のMetalやそれに準ずる効率的にデバイスへ描画命令を下せるシステムが構築されていくとドローコールが意味なくなる為、小さなテクスチャを数多く読みスパイクの低減等がトレンドになるかもしれません。

*4:プレハブのネスト化とインスタンス化の効率化を測ったネステッドプレハブ