Gestión de Bloques de Nivel en Videojuegos con Unity
Resumen
Aprende a generar niveles dinámicos en Unity con un único gestor que añade y elimina bloques según avanzas. Aquí verás cómo estructurar un gestor de nivel sólido en C# con métodos claros, patrón Singleton, y el uso efectivo de listas, arrays y bucles para mantener la escena limpia y estable desde un bloque plano inicial.
¿Qué resuelve el levelmanager en la generación del nivel?
Un bloque cero plano permite que el jugador empiece en una zona estable y conocida, evitando aparecer entre plataformas. A partir de ahí, el gestor debe añadir nuevos bloques al final, destruir los anteriores, generar los bloques iniciales y limpiar todo cuando el personaje muere.
¿Qué métodos públicos debe exponer el levelmanager?
Añadir un bloque nuevo al final: public voidAddLevelBlock.
Quitar el último o el que corresponda: public voidRemoveLevelBlock.
Eliminar todos los bloques de la escena: public voidRemoveAllLevelBlocks.
Preparar el inicio de la partida: public voidGenerateInitialBlocks.
usingSystem.Collections.Generic;usingUnityEngine;publicclassLevelManager:MonoBehaviour{publicstaticLevelManager SharedInstance;publicList<LevelBlock> allTheLevelBlocks =newList<LevelBlock>();publicList<LevelBlock> currentLevelBlocks =newList<LevelBlock>();publicTransform levelStartPosition;voidAwake(){if(SharedInstance ==null){ SharedInstance =this;}}voidStart(){GenerateInitialBlocks();}publicvoidAddLevelBlock(){}publicvoidRemoveLevelBlock(){}publicvoidRemoveAllLevelBlocks(){}publicvoidGenerateInitialBlocks(){for(int i =0; i <2; i++){AddLevelBlock();}}}
¿Cómo preparar la escena en unity para un inicio estable?
El objetivo es arrancar siempre en el mismo punto y con una configuración clara. Además, necesitas ver y localizar el gestor con facilidad usando un gizmo.
¿Cómo configurar el objeto vacío con gizmo y posición cero?
Crear un objeto vacío llamado LevelManager. Asignar un gizmo para identificarlo. Colocarlo en 0, 0, 0.
Asignar el script de C# al objeto LevelManager.
Crear un objeto vacío llamado “Level Start”. Añadir gizmo y colocarlo como referencia del inicio del nivel.
Usar alturas conocidas: Y en -4 y -13 para alinear con el punto de inicio mencionado. Ajustar Z a 0 para que quede sobre el anterior.
¿Cómo asignar prefabs y referencias en el inspector?
En LevelManager, arrastrar “Level Start” al campo levelStartPosition.
Preparar la lista allTheLevelBlocks con el tamaño adecuado según los prefabs creados.
Arrastrar el bloque 0 (plano) y el bloque 1 a las posiciones 0 y 1 respectivamente.
Recordatorio crucial: los índices empiezan en 0. Elemento 0 es el primero. Elemento 1 es el segundo.
¿Cómo funcionan listas, arrays y bucles en c# dentro de unity?
Para gestionar bloques dinámicos, necesitas estructuras que crezcan y se modifiquen en tiempo de ejecución. Además, un bucle simple puede invocar varias veces el mismo método sin esfuerzo.
¿Cuál es la diferencia entre arrays y listas?
Un array tiene tamaño fijo. No puedes añadir posiciones nuevas.
Una List es dinámica. Puedes añadir y quitar elementos cuando quieras.
Para bloques que se crean y destruyen en escena, una List es más versátil.
¿Cómo opera el bucle for para generar bloques iniciales?
Se recomienda generar dos bloques al inicio: el plano inicial y el siguiente para la transición.
Estructura del bucle: contador que arranca en 0, condición que se cumple mientras sea menor que 2, e incremento al final.
for(int i =0; i <2; i++){AddLevelBlock();}
Iteración 1: i = 0, se añade el primer bloque. Se incrementa i.
Iteración 2: i = 1, se añade el segundo bloque. Se incrementa i.
Salida: i = 2 ya no cumple i < 2, se detiene el bucle.
¿Por qué usar singleton en el gestor del nivel?
Debe existir solo un gestor de nivel. Evita conflictos de añadir y destruir a la vez.
Patrón Singleton: una instancia compartida accesible desde cualquier parte del juego mediante SharedInstance.
Ventajas prácticas.
Control centralizado del flujo del nivel.
Menos referencias manuales dispersas.
Código más claro y mantenible.
¿Te gustaría añadir más tipos de bloques o reglas para su aparición? Comparte tus ideas y preguntas en los comentarios.
La diferencia entre los humanos y los robots es la capacidad de repetir y repetir las mismas acciones tantas veces como sea necesario, y, hacerlo de la misma manera todas las veces si así lo requerimos. Los humanos no pueden hacer lo mismo más de 5 veces sin cansarse, equivocarse o rebelarse. - Juan Gabriel Gomila
#Epic!
En Sistemas Críticos (Los diarios de Matabot 1) de Martha Wells, Hay un robot que si se aburre y entra en crisis existencial
NOTA: Cada Level Block tiene su propio prefab y hay que darle su propio script de LevelBlock, así como de pasarle su StartPoint y EndPoint al script. (Arrastrarlos a los dos espacios de las variables públicas que creamos en el script)
Lo comento porque cuando quería agregar mi Level Block 0 a la Lista de levelBlocks del script del LevelManager (arrastrándolo), no me dejaba. Tardé en darme cuenta de que le hacía falta el script de LevelBlock a mi prefab de Level Block 0, así que ahí está el tip para los que tengan el mismo problema.
Muchas gracias!!
Arrays y Listas = Guardar colecciones pero…
Un Array es estático, no puedes añadir. Te quedas con lo declarado.
Una Lista es dinámica. puedes estar añadiendo y quitando
Buenas comunidad, estoy situando el LevelStart en la posición del StartPoint del primer Level Block pero tras situarlas en la misma posición me muestra que tienen distintas posiciones de transform:
StartPoint: -15, -5, 0
LevelStart: -10.75, -3.42, 0
No entiendo porque muestran datos distintos si los coloco en el mismo lugar, gracias de antemano.
He encontrado la respuesta de mi pregunta en el siguiente vídeo, resulta que las posiciones difieren porque son relativas al centro de sus respectivos padres, al ser hijos de diferentes padres me causaba esa duda.
No puedo adjuntar el prefab de level block a las variables element 0 y 1
Hola compañero, si aun tienes el problema, necesito un par de cosas para poder ayudarte.
Primero tu codigo, especificamnete en la parte de las listas.
Y en segunda, tus prefabs con sus componentes en el inspector.
Por ahora te puedo decir, que primero que nada debes asegurarte que los objetos tienen el script correspondiente a lvlblock, ademas de que tus listas hayan sido creadas con el objeto correspondiente a lvlblock
Cuando elaboramos juegos, que tanto creamos nuestras propias librerías con sus respectivas funciones? por que si y por que no las hacemos?
Siempre terminas haciendo librerías con funciones utilitarias
Tengo un pequeño problema y es al momento de querer arrastrar mi LevelBlock2 a la lista, me aparece el simbolo de nulo y no me deja agregarlo. Solo me funciona con el LevelBlock1. A que se puede deber???????
Hola compañero, asegurate de que el lvlBlock2 tiene el script correpondiente asignado, puesto que en el codigo se declara un array de objetos LVLBlock, por lo que no aceptara otro tipo de objeto, :D
Saludos
Soy yo o la sección de recursos está vacia?
Hola! Los recursos del proyecto que hizo el profe se encuentran en la primera clase del curso.
En mi interfaz de unity no se estan mostrando las variables All The Level Blocks y Current Level Blocks, solo se muestra start position, si creo una variable nueva si la muestra, pero esas no.
NOTA: Los arrays y las Listas son Objetos para guardar colecciones de GameObjet...
La LISTA es DINAMICA ... puede cambiar su tamaño a diferencia de los ARRAYS que tienen un tamaño predeterminado.
No puedo ver la sección de Recursos/Archivos en este video para poder usar los assets que menciona Juan al inicio del video.
Están en el primer video del curso
yo estoy usando mi propio asset. como llegaste haste este video y preguntas eso? 🤨
En mi interfaz de unity no se estan mostrando las variables All The Level Blocks y Current Level Blocks, solo se muestra start position, si creo una variable nueva si la muestra, pero esas no.
Por si a alguien le interesa, pueden hacer en lugar de
if(sharedInstance ==null){ sharedInstance =this}
Pueden usar el Null aware assignment
sharedInstance ??=this;
Ambos son lo mismo
** Procedimental
En vez de procedural? bueno yo hice investigación del tema y generalmente le llaman procedural, supongo que ambas están bien con tal que se entienda el concepto y se esté de acuerdo, igualmente el lenguaje evoluciona. Se le llama de demás formas también, generación automatizada, generación por algoritmos, por IA, etc.