前提
タイトルで、「trueになるやつとならないやつ」と書いていますが、結果的にはどちらもtrueになります。
しかし、trueになるタイミングが少し感覚と違うので、そこの違いをこの記事でははっきりさせたいと思います。
Unityの非同期ロード系の関数で、
- シーンを非同期でロードする、SceneManager.LoadSceneAsync()
- Resourcesのアセットを非同期で読み込むResources.LoadAsync<T>()
みたいなのがあると思います。(AssetBundleは一旦無視で進行します)
そしてこの2つはともに、UnityEngine.AsyncOperation
を返します。
※Resources.LoadAsync<T>()
はResourceRequest
を返しますが、AsyncOperation
を継承しているので実質同じ。
しかし、この2つのAsyncOperation
はAsyncOperation.IsDone
をきちんと返してくれるのでしょうか?以前にそこで詰まって頭の中で個チャゴチャになっていたので、もう一度検証してみました。
検証用コード
usingSystem.Collections;usingUnityEngine;usingUnityEngine.SceneManagement;publicclassSceneChangerTest:MonoBehaviour{voidStart(){StartCoroutine(Verify_LoadSceneAsync("scenename"));StartCoroutine(Verify_LoadAsync("path"));}IEnumeratorVerify_LoadSceneAsync(stringname){AsyncOperationoperation=SceneManager.LoadSceneAsync(name);operation.allowSceneActivation=false;while(!operation.isDone){Debug.Log(operation.progress*100f+"%読み込み完了");yieldreturnnull;}yieldreturnnewWaitForSeconds(0.5f);operation.allowSceneActivation=true;}IEnumeratorVerify_LoadAsync(stringname){ResourceRequestoperation=Resources.LoadAsync(name);while(!operation.isDone){Debug.Log(operation.progress*100f+"%読み込み完了");yieldreturnnull;}yieldreturnnewWaitForSeconds(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を返してくれるので、普通に使っても問題ないと思います。
検証は以上です。何か記事の中に問題がありましたら、コメントにてご指摘お願いします!