Tela de carregamento suave entre cenas


14

Criei uma tela de carregamento para exibir uma animação de carregamento enquanto a próxima cena está sendo carregada. Carrego a próxima cena de forma assíncrona com:

yield return SceneManager.LoadSceneAsync(scene,LoadSceneMode.Additive);

E também definido Application.backgroundLoadingPriority = ThreadPriority.Low;, mas o comportamento ainda é o mesmo que uma carga de nível regular.

Estou esquecendo de algo?

Comportamento esperado:

  • Saia do nível e desapareça.
  • A tela de carregamento é exibida.
  • Quando o carregamento estiver concluído, desapareça a tela de carregamento.
  • Desaparecer na próxima cena.

O que está acontecendo:

  • Saia do nível e desapareça.
  • A tela de carregamento é exibida, congelada
  • De repente, uma nova cena desaparece.

Quando o carregamento começa, o jogo apenas congela, como acontece com um carregamento normal de cena.

Eu li que você precisa definir allowSceneActivation = false, para que você desapareça a tela de carregamento e defina-a truepara permitir que a unidade termine de carregar, mas isso congela completamente meu jogo, como se a operação assíncrona nunca terminasse de carregar.


Eu tive esse problema e não encontrei nada aqui. Depois de pesquisar no Google, descobri o que estava causando esse problema. Decidi publicá-lo aqui para que outros pudessem encontrar a resposta facilmente. Informe-me se você gostaria de adicionar alguma melhoria à minha resposta / pergunta. Obrigado!
Leo

Respostas:


18

Quando você carrega uma cena, SceneManager.LoadSceneAsync()existem duas coisas acontecendo:

  • O jogoObjetos da cena são carregados na memória.
  • Então a cena inteira é ativada. Todos os retornos de chamada Awake () e Start () serão chamados para os objetos na cena.

A segunda etapa, habilitando a cena, é o que realmente congela a unidade, porque a unidade está executando todos esses retornos de chamada de inicialização em seus scripts em um único ciclo.

De fato, definir SceneManager.LoadSceneAsync().allowSceneActivationcomo falsefará com que a operação assíncrona conclua apenas a primeira etapa do processo e esperará até que esteja definida truepara iniciar a segunda parte do processo.

Mas se você definir allowSceneActivationa falsee rendimento no retorno de chamada como este, você vai congelar o seu jogo para o bem;

AsyncOperation AO = SceneManager.LoadSceneAsync(scene,LoadSceneMode.Additive); 
AO.allowSceneActivation = false;
yield return AO;

//Fade the loading screen out here

AO.allowSceneActivation = true;

Por quê? Como você está dizendo à operação assíncrona para não prosseguir com a segunda etapa do carregamento da cena, a operação nunca será concluída.

Se você deseja saber quando a primeira parte da operação está pronta, para prosseguir com a segunda, você precisa confiar AsyncOperation.progress. Este valor será interrompido 0.9fassim que estiver aguardando a allowSceneActivationsinalização.

Deve ser algo como isto:

AsyncOperation AO = SceneManager.LoadSceneAsync(scene,LoadSceneMode.Additive); 
AO.allowSceneActivation = false;
while(AO.progress < 0.9f)
{
    yield return null
}

//Fade the loading screen out here

AO.allowSceneActivation = true;

Se você deseja que a ativação da cena não congele seu jogo, você deve manter os retornos de chamada Desperta e Iniciar em um mínimo e inicializar seus scripts em uma rotina por vários ciclos.


0

Eu tive exatamente o mesmo problema no Unity 5.6 e já havia tentado adicionar as declarações de rendimento. Foi o próprio LoadSceneAsync que estava bloqueando o thread principal do Unity e impedindo que a cena atual mostrasse bem qualquer progresso no carregamento.

Parece ser um bug no Unity, até onde eu sei. Quando minha cena era menos complexa, meu código funcionava perfeitamente, com uma transição suave. Uma vez maior, o Unity bloqueou o thread por cerca de 6 segundos, enquanto o jogo fica como 'não respondendo', apesar da operação supostamente ser "assíncrona"

A maneira como resolvi o problema foi examinar minha iluminação. Houve erros enormes no passado com a iluminação e esse recurso. Então eu examinei meus objetos e descobri que tinha um holofote em um objeto (mesmo que estivesse desativado ...)

Apaguei os holofotes e viva! Cena carrega assíncrona corretamente! Sem bloqueio!


Antes da edição, esta postagem não oferecia uma solução para o problema. Tudo bem agora que você adicionou uma correção, mas, no futuro, se você quiser dizer "Eu também estou com esse problema", não deverá usar respostas para esse fim. Ganhar um pequeno representante permitirá que você comente as postagens existentes ou ofereça uma recompensa às perguntas para incentivar novas respostas.
DMGregory
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.