Как исправить баг повторной асинхронной загрузки сцены?



@logpol32

У меня есть сцена StartScene с кнопкой «Новая игра». По нажатию на эту кнопку запускается «промежуточная» сцена загрузки LoadingScene.
//  Клик по кнопке "Новая игра" на сцене StartScene .
SceneManager.LoadScene("LoadingScene");

LoadingScene, используя корутину, выводит прогресс загрузки и загружает сцену Scene1.

AsyncOperation asyncOperation;
public Image loadingBarFill;
public Text loadingText;
private string sceneName="Scene1";

void Start()
{
    StartCoroutine(LoadSceneCoroutine());
}



IEnumerator LoadSceneCoroutine()
{
    yield return new WaitForSeconds(1f);
    asyncOperation = SceneManager.LoadSceneAsync(sceneName);
    while(!asyncOperation.isDone)
    {           
        float progress = asyncOperation.progress/0.9f;
        loadingBarFill.fillAmount = progress;
        loadingText.text = "Загрузка"+string.Format("{0:0}%", progress*100f);
        yield return 0;
        
    }
    
}

Самая обычная загрузка уровня через промежуточную сцену.

В первый раз всё работает. StartScene -> LoadingScene -> Scene1. Всё хорошо — Scene1 загружена.
Далее на Scene1 я нажимаю на кнопку — «Вернуться в главное меню игры» и перехожу к сцене StartScene.

//  Клик по кнопке "Вернуться в главное меню игры" на сцене Scene1.
SceneManager.LoadScene("StartScene ");

И снова повторяю действия. Нажимаю кнопку «Новая игра» — перехожу на сцену LoadingScene и ничего не происходит. Прогресс бар стоит на нуле, сцена Scene1 не загружается.

Без асинхронной загрузки, простыми SceneManager.LoadScene всё загружается.
Я знаю, что при асинхронной загрузке, надо выгружать сцену. Пробовал разные варианты выгрузки — не помогало.
Как исправить баг повторной асинхронной загрузки сцены?


Решения вопроса 0


Ответы на вопрос 1



@Ente

Можно на стартовой сцене создать скрипт менеджер, который будет управлять асинхронными загрузками и выгрузками сцен. Основной смысл в том, чтобы асинхронная загрузка ждала асинхронной выгрузки всех сцен.

Создается два листа, scenesToLoad и scenesToUnload. Далее подписываемся на события SceneManager.sceneLoaded
SceneManager.sceneUnloaded, чтобы понимаеть, что у нас загрузилось и выгрузилась. Когда мы хотим загрузить сцену, мы помещаем ее имя в scenesToLoad (когда выгрузить — в scenesToUnload) и не загружаем ее асинхронно до тех пор, пока все асинхронные сцены не будут выгружены (scenesToUnload содержит хоть что-то). Как только лист scenesToUnload опустеет — грузим асинхронно все сцены, которые находятся в листе sceneToLoad.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *