Quantcast
Channel: C#タグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 9374

UnityのAsyncOperation.isDoneでtrueになるやつとならないやつ

$
0
0

前提

タイトルで、「trueになるやつとならないやつ」と書いていますが、結果的にはどちらもtrueになります。
しかし、trueになるタイミングが少し感覚と違うので、そこの違いをこの記事でははっきりさせたいと思います。

Unityの非同期ロード系の関数で、
- シーンを非同期でロードする、SceneManager.LoadSceneAsync()
- Resourcesのアセットを非同期で読み込むResources.LoadAsync<T>()
みたいなのがあると思います。(AssetBundleは一旦無視で進行します)

そしてこの2つはともに、UnityEngine.AsyncOperationを返します。
Resources.LoadAsync<T>()ResourceRequestを返しますが、AsyncOperationを継承しているので実質同じ。

しかし、この2つのAsyncOperationAsyncOperation.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()
isDonefalsetrue
状態isDoneが一生trueにならないのでスタックきちんとtrueになり、インスタンス化も成功

そうなんです。LoadSceneAsync()のときのみ、isDoneがtrueにならずスタックします。
同様に、コード内のoperation.progressも0.9fで止まってしまいます。
この場合のisDoneは、シーン遷移が完了してからtrueになるのでロードした段階ではfalseです。

Resources.LoadAsync()は、ロード完了した段階でisDoneがtrueを返してくれるので、普通に使っても問題ないと思います。

検証は以上です。何か記事の中に問題がありましたら、コメントにてご指摘お願いします!


Viewing all articles
Browse latest Browse all 9374

Latest Images

Trending Articles