【Unity】非同期でシーンを読み込んでキャンセルする

投稿者: | 2020-08-13

シーンの開始と共にメインのゲームのシーンを非同期で読み込んで、スタートボタンが押されたら遷移し、キャンセルが押されるとスタートメニューなどの別のシーンに遷移してみました。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;

public class AsyncLoadScene : MonoBehaviour
{
    [SerializeField] Text text;
    bool ready = false;
    AsyncOperation asyncOperation;

    // Start is called before the first frame update
    void Start()
    {
       Invoke("StartLoadScene", 3f);
    }

    public void Cancel()
    {

        SceneManager.LoadScene("StartMenu", LoadSceneMode.Single);

    }

    public void StartGame()
    {
        ready = true;

    }

    void StartLoadScene()
    {
        StartCoroutine("LoadScene");
    }


    IEnumerator LoadScene()
    { 

        asyncOperation = SceneManager.LoadSceneAsync("game1");

        asyncOperation.allowSceneActivation = false;

        while (!asyncOperation.isDone)
        {

            text.text = "Loading progress: " + (asyncOperation.progress * 100) + "%";
            
            if (asyncOperation.progress >= 0.9f)
            {

                text.text = "Press the \"Start\" button to continue";

                if(ready) asyncOperation.allowSceneActivation = true;

            }

            yield return null;
        }
    }
}

参考:https://docs.unity3d.com/ja/current/ScriptReference/AsyncOperation-allowSceneActivation.html

開始とともに、シーンをロードするためのコルーチンをスタートさせます。その後進捗が90%を超えてもスタートボタンが押されなければ遷移しないようにしたいのですが、Start()にStartCoroutineを直接書くと、なぜかすぐに遷移してしまいます。

参考ページではボタンを押したらロードが始まるようになっていますが、Invoke()を使って数秒後に始まるようにしてもできました。

キャンセルする

キャンセルして別のシーンに遷移したときに、非同期で読み込んでいたシーンはどうなるでしょうか。SceneManager.LoadSceneの第2引数でモードを指定でき、これをSingleにすると読み込まれた全てのシーンを閉じて重複しないように新しくシーンを読み込めるようなので使ってみました。

新しいシーンでは今読み込まれているシーンの数をコンソールに表示します。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;


public class SceneCount : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        Debug.Log(SceneManager.sceneCount);
    }
}

すると、キャンセルした後はシーンが1つしか読み込まれていないのがわかりました。また、プロファイラーでは非同期の読み込みが始まるとテクスチャやマテリアル、オブジェクトが急に増えて、キャンセルすると急に減るようなので、問題なくキャンセルできているのではないかなと思います。

LoadSceneModeをAdditiveにすると、キャンセルしてもなぜかメインのゲームのシーンに遷移し、コンソールにはシーン数が2と表示されます。

LoadSceneModeを省略してもSingleと同じように重複せずに読み込めました。

コメントを残す

メールアドレスが公開されることはありません。