Pantalla de carga suave entre escenas

14

Creé una pantalla de carga para mostrar una animación de carga mientras se carga la siguiente escena. Cargo la siguiente escena de forma asincrónica con:

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

Y también establecido Application.backgroundLoadingPriority = ThreadPriority.Low;, pero el comportamiento sigue siendo el mismo que una carga de nivel regular.

¿Me estoy perdiendo de algo?

Comportamiento esperado:

  • Nivel de salida y desvanecerse.
  • Aparece la pantalla de carga.
  • Una vez que se realiza la carga, desaparece la pantalla de carga.
  • Se desvanecen en la siguiente escena.

Qué está pasando:

  • Nivel de salida y desvanecerse.
  • Aparece la pantalla de carga, congelada
  • De repente, una nueva escena se desvanece.

Una vez que comienza la carga, el juego simplemente se congela, como con una carga de escena normal.

Leí que tiene que configurar allowSceneActivation = false, para que pueda desvanecer la pantalla de carga, y luego configurarla truepara que la unidad termine de cargar, pero esto congela completamente mi juego, como la operación asincrónica nunca termina de cargarse.

León
fuente
Tuve este problema y no encontré nada aquí. Después de buscar en Google descubrí qué estaba causando este problema. Decidí publicarlo aquí para que otros puedan encontrar la respuesta fácilmente. Avíseme si agregaría alguna mejora a mi respuesta / pregunta. ¡Gracias!
Leo

Respuestas:

18

Cuando carga una escena, en SceneManager.LoadSceneAsync()realidad están sucediendo dos cosas:

  • Los objetos del juego de la escena se cargan en la memoria.
  • Entonces toda la escena está habilitada. Todas las devoluciones de llamada Awake () y Start () serán llamadas para los objetos en la escena.

El segundo paso, habilitar la escena, es lo que realmente congela la unidad, porque la unidad está ejecutando todas esas devoluciones de llamada de inicialización en sus scripts en un solo ciclo.

De hecho, establecer SceneManager.LoadSceneAsync().allowSceneActivationa falsehará que la operación asincrónica complete solo el primer paso del proceso y esperará hasta que se configure truepara comenzar la segunda parte del proceso.

Sin embargo, si se establece allowSceneActivationa falsey el rendimiento en la devolución de llamada como ésta, se le congelará su juego para bien;

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

//Fade the loading screen out here

AO.allowSceneActivation = true;

¿Por qué? Debido a que le está diciendo a la operación Async que no continúe con el segundo paso de la carga de la escena, la operación nunca se completará.

Si desea saber cuándo está lista la primera parte de la operación, para continuar con la segunda, debe confiar AsyncOperation.progress. Este valor se detendrá en 0.9fcuanto esté esperando la allowSceneActivationbandera.

Debería ser algo como esto:

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;

Si desea que la activación de la escena no congele su juego, debe mantener sus devoluciones de llamada de Despertar e Iniciar al mínimo, e inicializar sus scripts en una rutina a través de varios ciclos.

León
fuente
0

Tuve exactamente el mismo problema en Unity 5.6, y ya había intentado agregar las declaraciones de rendimiento. Fue el propio LoadSceneAsync el que bloqueó el hilo principal de Unity y evitó que la escena actual mostrara bien cualquier progreso de carga.

Parece que es un error en Unity por lo que puedo decir. Cuando mi escena era menos compleja, mi código funcionaba genial, una transición suave. Una vez que se hizo más grande, Unity bloqueó el hilo durante unos 6 segundos, todo el tiempo mientras el juego se presenta como "no responde" a pesar de que la operación supuestamente es "asíncrona"

La forma en que resolví el problema fue mirar mi iluminación. Ha habido errores masivos en el pasado con la iluminación y esta característica. Así que revisé mis objetos y descubrí que tenía un foco en un objeto (aunque estaba deshabilitado ...)

Eliminé el centro de atención y ¡hurra! ¡La escena se carga asíncrona correctamente! ¡Sin bloqueo!

Señor de la pila
fuente
Antes de la edición, esta publicación en realidad no ofrecía una solución al problema. Está bien ahora que ha agregado una solución, pero en el futuro si quiere decir "Estoy teniendo este problema también", no debe usar respuestas para ese propósito. Ganar un pequeño representante te permitirá comentar publicaciones existentes o recompensar las preguntas para fomentar nuevas respuestas.
DMGregory