Optimiza el reinicio de tu videojuego en Unity con un flujo robusto que limpia el nivel, genera el suelo inicial y evita artefactos visuales. Aquí verás cómo integrar el Game Manager y el Level Manager con llamadas precisas y un orden correcto, además de ajustes prácticos de colliders y cámara para una experiencia fluida.
¿Cómo limpiar bloques al morir y reiniciar en Unity?
Para cerrar correctamente una partida y empezar otra sin residuos, es clave el orden en el set game state. Antes de reiniciar el controlador y el personaje, se debe limpiar la escena y volver a generar los bloques iniciales. Así desaparecen los restos del intento anterior y evitas que queden bloques superpuestos.
¿Qué llamadas debes hacer en Level Manager?
Usa la shared instance del singleton para centralizar la gestión del nivel.
Primero limpia todo con RemoveAllLevelBlocks.
Luego genera el suelo con GenerateInitialBlocks.
Finalmente, arranca el controlador del jugador.
// Dentro de SetGameState cuando pasas a InGameLevelManager.SharedInstance.RemoveAllLevelBlocks();LevelManager.SharedInstance.GenerateInitialBlocks();controller.StartGame();
¿Por qué evitar solapamientos de bloques?
Si generas bloques sin limpiar, se apilan y crean artefactos visuales feos.
La limpieza previa garantiza un estado consistente del nivel.
El StartGame debe ocurrir tras la regeneración de bloques para que el personaje aparezca con suelo.
Punto clave: el StartGame llama a SetGameState, y este orquesta la limpieza y preparación de escena para el estado in game.
¿Cuándo retrasar la recarga con invoke?
A veces conviene dar un margen al motor para completar destrucciones antes de generar nuevos bloques. Una técnica sencilla es extraer la lógica en una función ReloadLevel y usar Invoke con un pequeño retardo. Sin embargo, en el caso descrito, el problema real fue no guardar el script: tras guardar, el retardo no fue necesario.
¿Cómo estructurar la recarga del nivel?
Extrae la regeneración en ReloadLevel.
Limpia primero los bloques antiguos.
Si lo necesitas, usa Invoke por unas décimas de segundo.
voidReloadLevel(){ LevelManager.SharedInstance.GenerateInitialBlocks(); controller.StartGame();}// Al entrar en InGameLevelManager.SharedInstance.RemoveAllLevelBlocks();// Opción si hace falta esperar:Invoke(nameof(ReloadLevel),0.1f);// Si no hace falta, llama directamente:// ReloadLevel();
Si ves “más bloques de la cuenta”, verifica primero que has guardado el método de limpieza en el Level Manager. Guardar el script evita falsos diagnósticos.
¿Qué ajustes de jugabilidad y cámara revisar?
Durante las pruebas, el flujo mostró que la exit zone destruye el bloque anterior y genera el siguiente con normalidad. Aun así, hay detalles de contacto y cámara que conviene revisar para una experiencia pulida.
¿Cómo prevenir atascos por colliders?
Deja espacio suficiente entre elementos para el collider del personaje.
Si no hay espacio, superpone colliders adyacentes ligeramente.
Ajusta el box collider del jugador para hacerlo un poco más pequeño.
Evita distancias excesivas entre piezas del terreno.
¿Qué pasa con el barrido de cámara al reiniciar?
Se observa un “barrido hacia atrás” al reiniciar porque el script de barrido automático de la cámara existe pero no se ha invocado.
La solución pendiente es invocarlo en el momento adecuado del ciclo de estado, tras la regeneración del nivel.
Además, recuerda la aleatoriedad del generador: a veces aparecen muchos bloques sencillos seguidos y otras, más complejos. Es normal en un sistema de contenido dinámico.
¿Te pasó lo del script sin guardar o tienes otra duda sobre el orden de llamadas en Game Manager y Level Manager? Cuéntalo en los comentarios y comparte tu solución.
No se si mi solución es muy overkill pero creo que reiniciar el nivel desde cero tiene sentido para un runner, por lo que mi solución es solo recargar la scene
//logica del GameManagerelseif(newGameState ==GameState.gameOver){GameManager.sharedInstance.currentGameState=GameState.gameOver;SceneManager.LoadScene("SampleScene");}
Yo hubiera hecho lo mismo
Otra forma de usar el invoke:
Invoke(nameof(ReloadLevel),0.1f);
Me encanta, mantiene lo tipado de C#
Buenisimo, gracias por compartir!
Yo desde el principio vi ese círculo en el nombre del script, y pensé: "¿Eso no significa que no ha guardado el script?"
Me andan ocurriendo mini fallos y es que ando colocando mal algunos codigos, necesito estar mas atento.
Ponte trucha
no se si lo cambiaremos después o algo así o no es parte del diseño pero creo que lo de limpiar el currentlevel sedeveria hacer al cambiar al estado de gameover porque supongo que si quiero cambiar de menu a ingame lo va reiniciar todo (porque aria esto por ejemplo para poder gastar los coleccionables y comprar un booster de speed o no se algo o solo poner pause)
yo por eso quite el level block 0 del random
para que hay que destriuir bloques?? para que el juego no pese tanto ? por performance ? no gaste tanto recurso ?
Para mejorar el performance. En videojuegos siempre es importante mantener al mínimo el uso de recursos necesarios. Sí el jugador no no ve ni necesita un asset no hay razón para mantenerlo en la escena.
GIF
Tengo el siguiente problema. El bucle For del LevelManager no finaliza nunca, es decir, me genera los dos bloques iniciales pero sigue construyendo bloques sin parar. El personaje nunca llega a caer al vacío, y quisiera que funcionase para crear distintas partidas con niveles de dificultad diferentes.
Aparicion de bloques despues de destruir los anteriores