(:3[kanのメモ帳]

個人ゲーム開発者kan.kikuchiのメモ的技術ブログ。月木更新でUnity関連がメイン。

Resourcesのアセットを非同期でロードする【Unity】


このエントリーをはてなブックマークに追加

この記事でのバージョン
Unity 2017.2.0f3


はじめに

今回はResourcesのアセットを非同期でロードする方法のご紹介です!

ロードするサイズや量があり、普通にロードしてしまうと処理落ちしてしまう時に使えます。


Resources.LoadAsync

Resourcesのアセットを非同期でロードするにはResources.LoadAsyncを使います。



非同期ロードの流れは以下のような感じです。

  1. Resources.LoadAsyncでロードを開始し、ResourceRequestを取得
  2. ResourceRequestのisDoneがtrueになるまで待機
  3. ResourceRequest.assetでロードしたアセットを取得


private void Start(){
  //Resources/Background1を非同期でロードする
  StartCoroutine (LoadAsync("Background1"));
}

//非同期でロードする
private IEnumerator LoadAsync(string filePath){
  //非同期ロード開始
  ResourceRequest resourceRequest = Resources.LoadAsync<Sprite> (filePath);

  //ロードが終わるまで待機(resourceRequest.progressで進捗率を確認出来る)
  while(!resourceRequest.isDone) {
    yield return 0;
  }

  //ロード完了、resourceRequest.assetからロードしたアセットを取得
  Sprite sprite = resourceRequest.asset as Sprite;
}



注意点や欠点

上記の通り、非同期でロードする事自体はかなり簡単に行えますが、

色々と注意点や欠点もあるのでそちらも紹介しておきます。


Prefabのロードでカクつく

Prefabは非同期でロードしているはずなのにカクつく場合があります。


その原因はそのPrefab自体は非同期でロードしていても

Prefabに関係するテクスチャやオーディオ等のロードは非同期で行われていないからです



なので、Prefabを非同期でロードしているのにカクつく場合は

そのPrefabに関係する他のアセットを予めロードしておくようにしましょう。


Audio Clipのロードでカクつく

Audio Clipは非同期でロードしているはずなのにカクつく場合があります。

その原因はメモリへのロードによる負荷で、特にBGM等のサイズが大きいもので発生しやすいです。


なので、Audio Clipを非同期でロードしているのにカクつく場合は

Load TypeをStreamingにし、再生しながらロードするようにしましょう。


f:id:kan_kikuchi:20180204163049j:plain


LoadAllAsyncはない

Loadの非同期版のLoadAsyncがあるのだから

LoadAllの非同期版のLoadAllAsyncもありそうですが、残念ながらありません。


なお、ドキュメントにはLoadAsyncでフォルダを指定すれば出来そうな感じに書いありますが、

path
Pathname of the target folder. When using the empty string (i.e., ""), the function will load the entire contents of the Resources folder.

Google翻訳
ターゲットフォルダのパス名。 空の文字列( "")を使用すると、関数はResourcesフォルダの内容全体を読み込みます。


どうやらドキュメントのミスっぽいです。

(おそらくResources.LoadAllの文言をコピペしてそのままになっている)


Resource.LoadAllAsync - where is it? | Unity Community


MultipleのSpriteは非同期ロード出来ない

LoadAllに該当する非同期処理がないので、

当然、Sprite ModeをMultipleに設定した全Spriteを非同期で取得するという事も出来ません。


How do you use Resources.LoadAsync with a multiple frame sprite? | Unity Community


おわりに

簡単に使えそうで結構癖があるResources.LoadAsyncでしたが、使い慣れれば有用なメソッドです。


なお、どうしてもLoadAllAsyncのような事がしたい場合は

AssetBundleでまとめて、AssetBundle.LoadAllAssetsAsyncを使うのが良いかと思われます。