7
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

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

Last updated at Posted at 2021-01-17

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

Unityの非同期ロード系の関数で、

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

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

しかし、この2つのAsyncOperationAsyncOperation.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を返してくれるので、普通に使っても問題ないと思います。

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

7
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?