#前提
タイトルで、「trueになるやつとならないやつ」と書いていますが、結果的にはどちらもtrueになります。
しかし、trueになるタイミングが少し感覚と違うので、そこの違いをこの記事でははっきりさせたいと思います。
Unityの非同期ロード系の関数で、
- シーンを非同期でロードする、
SceneManager.LoadSceneAsync()
- Resourcesのアセットを非同期で読み込む
Resources.LoadAsync<T>()
みたいなのがあると思います。(AssetBundleは一旦無視で進行します)
そしてこの2つはともに、UnityEngine.AsyncOperation
を返します。
※Resources.LoadAsync<T>()
はResourceRequest
を返しますが、AsyncOperation
を継承しているので実質同じ。
しかし、この2つのAsyncOperation
はAsyncOperation.isDone
をきちんと返してくれるのでしょうか?以前にそこで詰まって頭の中で個チャゴチャになっていたので、もう一度検証してみました。
#検証用コード
using System.Collections;
using UnityEngine;
using UnityEngine.SceneManagement;
public class LoadAsyncTest : MonoBehaviour {
void Start() {
StartCoroutine(Verify_LoadSceneAsync("scenename"));
StartCoroutine(Verify_LoadAsync("path"));
}
IEnumerator Verify_LoadSceneAsync(string name) {
AsyncOperation operation = SceneManager.LoadSceneAsync(name);
operation.allowSceneActivation = false;
while (!operation.isDone) {
Debug.Log(operation.progress * 100f + "%読み込み完了");
yield return null;
}
yield return new WaitForSeconds(0.5f);
operation.allowSceneActivation = true;
}
IEnumerator Verify_LoadAsync(string name) {
ResourceRequest operation = Resources.LoadAsync(name);
while (!operation.isDone) {
Debug.Log(operation.progress * 100f + "%読み込み完了");
yield return null;
}
yield return new WaitForSeconds(0.5f);
Instantiate((GameObject) operation.asset);
}
}
LoadLevelAsync()
ではシーンを非同期でロードして、whileでisDoneがtrueになるまで待っています。
LoadAssetAsync()
ではResourcesのアセットを非同期でロードして、同様の処理を行っています。
#検証結果
ScneneManager.LoadSceneAsync() | Resources.LoadAsync() | |
---|---|---|
isDone | false | true |
状態 | isDoneが一生trueにならないのでスタック | きちんとtrueになり、インスタンス化も成功 |
そうなんです。LoadSceneAsync()のときのみ、isDoneがtrueにならずスタックします。
同様に、コード内のoperation.progress
も0.9fで止まってしまいます。
この場合のisDoneは、シーン遷移が完了してからtrueになるのでロードした段階ではfalseです。
Resources.LoadAsync()
は、ロード完了した段階でisDoneがtrueを返してくれるので、普通に使っても問題ないと思います。
検証は以上です。何か記事の中に問題がありましたら、コメントにてご指摘お願いします!