Optimiza la generación procedural en Unity con un enfoque robusto: usa object pooling y un level manager para añadir bloques sin saturar la RAM. Aquí verás cómo controlar la aleatoriedad con Random.Range, alinear puntos de entrada y salida, y mantener el rendimiento sin bajadas de frames.
¿Por qué usar object pooling y un level manager?
La tentación de “añadir y añadir bloques” acaba en overflow de memoria, bajadas de frames y mala experiencia. La solución es reciclar objetos ya instanciados: el object pooling mantiene un conjunto de elementos listos para reutilizar, evitando el coste de instanciar en tiempo real.
Instanciar en exceso consume RAM y provoca lag.
Reciclar objetos reduce el coste computacional.
El level manager centraliza crear, mover, posicionar y destruir bloques.
¿Qué problema evita el object pooling?
Evita que el juego crezca en memoria sin control. En vez de crear cada bala o bloque desde cero, se reutiliza desde una “recámara” de objetos precargados.
¿Cómo se reciclan objetos como balas?
Se mantienen listas de objetos ya instanciados (10, 20, 50, 100). Cuando uno termina su ciclo (colisiona o sale de pantalla), vuelve a la recámara para usarse de nuevo.
¿Cómo se añade un nuevo bloque con aleatoriedad controlada?
El método para “añadir bloque” parte de una idea clave: el primer bloque no es aleatorio, es el de la posición 0 para no frustrar al jugador. A partir del segundo, se usa Random.Range con distribución uniforme, donde todos los bloques disponibles son equiprobables.
Genera un índice aleatorio con Random.Range entre 0 y el tamaño de la lista.
Prepara una spawn position con Vector3.zero y calcúlala según el caso.
Para el primer bloque: usa el índice 0 y colócalo en level start position.
Para los siguientes: coloca el bloque en el exit point del bloque anterior.
Código base para el índice aleatorio y la posición inicial:
int randomIdx = Random.Range(0, allTheLevelBlocks.Count);Vector3 spawnPosition = Vector3.zero;
Primer bloque fijo en el inicio del nivel:
if(currentLevelBlocks.Count ==0){var block =Instantiate(allTheLevelBlocks[0]); spawnPosition = levelStartPosition.position;// ... (sigue con corrección, parent y add)}
Bloques siguientes con selección uniforme:
else{var block =Instantiate(allTheLevelBlocks[randomIdx]); spawnPosition = currentLevelBlocks[currentLevelBlocks.Count -1].exitPoint.position;// ... (sigue con corrección, parent y add)}
Haz que todos los bloques sean hijos del level manager para mantener la escena ordenada. Usa SetParent con false para no heredar transformaciones del padre:
block.transform.SetParent(this.transform,false);
¿Cómo se alinea el start point con el exit point?
Para “enganchar” los bloques como eslabones, alinea el start point del nuevo bloque con la spawn position calculada (final del anterior). Aplica una corrección vectorial restando coordenadas. En 2D, la z es 0.
Random.Range: distribución uniforme para elegir bloques con igual probabilidad.
Primer bloque determinista: índice 0 para facilitar el onboarding del jugador.
Enlace por puntos: usar exit point del último y start point del nuevo.
Parentesco seguro: SetParent(this.transform, false) para no heredar escalados o rotaciones.
¿Cómo probar y ajustar la generación procedural?
Valida visualmente que los bloques se enganchan bien y que no hay artefactos.
Elimina el bloque placeholder antes de ejecutar: ya no es necesario.
Pulsa Play y comprueba la generación dinámica.
En GenerateInitialBlocks, sube temporalmente a 20 para ver variedad.
Verifica que todos terminan en la misma altura (ejemplo: y = -4).
Haz zoom out y revisa el encadenado de rombos, cuadrados y círculos.
Recupera el número inicial (por ejemplo, 2) cuando acabes la prueba.
Próximo paso natural: seguir al personaje y ajustar el manager para destruir bloques cuando ya no hagan falta.
¿Tienes dudas o quieres compartir tu implementación? Escribe un comentario con tu avance y cualquier bloqueo: entre todos podemos mejorar el flujo de generación procedural en Unity.
Si saben que su código está bien, pero al generar los niveles se desfasan, no olviden que su LevelManager debe de estar en la posición 0,0,0 (x,y,z)
Te adoro. Justo tenía ese problema. Revisé todo el código y todos los prefabs, startpoints y endpoints. Me has salvado, estoy agradecido.
Como te adoro meeen, justo lo que buscaba, ya decía yo porque me pasaba eso si estaba bien el codigo-
😪 es satisfactorio decir que he podido arreglar un error que se me presento en el proceso de la clase, fue causado por la cordenada z en los EndGame y StartGame, aunque no se utilizaba esta cordenada se alteraba haciendo cambios minimos de 0.425 o 0.28 etc, a lo que al intentar de aliniarce StartGame y EndGame no se encontraban y me daba un mundo cada vez mas alto (vertical) y no normal (horizontal). Psss no es la gran cosa el descubrimiento pero es satisfactorio encontrar el error que tantos problemas me dio 😅😁
Gracias por compartirlo, a alguien más le puede pasar
Como funciona la correccion, mientras el metodo AddLevelBlock es llamado.
.
El primer bloque de juego es instanciado de acuerdo a los valores obtenidos en la corrección.
.
El segundo bloque de juego es instanciado de acuerdo a los valores obtenidos en la corrección.
Me sirvió para entender, muchas gracias.
Por si quieren hacer la tarea: Random.Range - Unity 🤓 👌 📖.
muchas gracias por el enlace
Instantiate: Optimiza creando clones de los Prefab. Mas informacion sobre su funcionamiento y reciclaje de de balas en el siguiente link :
Entre a este curso para aprender a programar C# para videojuegos, pero no estoy aprendiendo nada, sigo el curso al pie de la letra pero cada que se programa no comprendo el porque de las cosas? sientp que hago el curso pero no aprendo a programar que me sugieren hacer?
Vi el temario de tu curso y veo que solo enseñan temas de videojuegos saltandonce los fundamentos de programación, mi recomendación serias que tomaras los curso de fundamentos de programación para que entiendas lo que están programando, si aun así no aprendes o crees que el problema sea como te enseñan, te recomiendo que vayas a udemy.
Si vienes de cero sin saber programar te recomiendo hacer el de Programación básica , aunque ahí se usa javascript te ayuda a aprender los fundamentos de practicamente cualquier lenguaje de programación, y si tienes mas dudas puedes cursar los cursos de la carrera de Fundamentos de programación
Se me complicó un poco el entender la linea 51. Teniendo en cuenta que en mi caso el levelStart es -10 en x y el startPoint del bloque 0 es -14 entonces tenemos en la operación de la corrección para el eje x: 10 - (-14) da un +4. Los bloques se ubican haciendo coincidir la coordenada dada con su centro. Entonces la corrección mueve 14 puntos positivos el bloque, que es la misma distancia que hay desde el centro del bloque hasta el punto inicial del bloque del nivel. Espero esto los ayude a entender mejor. Las coordenadas en el bloque son relativas a el centro del mismo.
Tambien se puede dejar el código así para que quede un poco más claro
Yo hice que el lvl0 solo aparezca solo al principio
en el random(1, allTheLevelBlocks.Count)
buena idea, luego se puede cambiar el valor "1" por otro mayor y tener niveles fijos en tal o cual parte que deseemos :D
A mi solo se me generan 2 bloques nada mas, pero al profe se le generan un monton, a que se puede deber? :'(
Si eso es en el incio del juego, es debido a la cantidad de repeticiones que tienes programadas en el bucle de generacion inicial de niveles
Si te refieres a otra cosa hazmelo saber y te ayudo, igual si me muestras tu codigo seria de gran ayuda para ayudarte :D
Buenas, alguien sabe como hacer que mi cámara
detecte mi player??
Una manera es poner en la Main Camera- Transform- Position el eje z en -1
Gracias Genio!!
No me ha quedado claro algo... ¿por que al asignarle el resultado de la resta de las posiciones del punto final del bloque actual y el inicial del nuevo bloque, a la posición al nuevo bloque, da como resultado el correcto enlazamiento entre ambos bloques?
En pocas palabras, en código lo entiendo, pero en las matemáticas no me cuadra, no se si estoy pasando por alto algo en lo que refiere a las coordenadas globales y locales.
Usa una valor intermedio (spawnPosition) - blockPosition = **correction **
que cada que se crea un nuevo escenario ese valor se le asigna a la posición inicial para que cuadren
Me ha sucedido un error extraño: no se colocan adecuadamente los level block, el primero aparece en la derecha inferior de la camara, y los siguientes a la derecha superior, probe con 20 level blocks y forman una escalera, mis end points y start point tienen la posición correcta y el padre de los level block es 0,0,0. ¿alguien sabe como arreglarlo?
Podrías subir una imagen de lo que sucede exactamente para entender mejor tu problema?
Prueba de 10 bloques:
La camara esta hasta abajo.
Un mejor metodo para que el spawn no se estropee si el Level Manager no está en el origen es este.
El nuevo bloque toma la posicion del spawn point
El valor de correccion ahora sera igual a la posicion actual del bloque, mas la resta de la posicion actual del bloque menos las posicion del start point del bloque.
De este modo se garantiza que la generacion de bloques emparentados al LevelManager sea correcta
!image
Si les da un error de null en el 'Instantiate", les recuerdo (para que no les pase como a mi) que para todos los bloques de niveles se usa el mismo script. :P
Alguien podría explicarme por que se utiliza LevelBlock como tipo de dato para Block... y por que las LISTAS tienen como tipo de dato LevelBlocks
Se utiliza LevelBlock para obtener el punto inicial y punto final que son miembros de esa clase.
Cuando se instancia una clase LevelBlock, lo que se instancia es el objeto de juego al que está unido (el prefab).
Porque hay que usar la funcion SetParent o hacer que todos los bloques pasen hacer hijos del LevelManager ? Min 8:40
porque siendo hijos del levelmanager el script tiene acceso al startposition y endposition
Tengo un problema, cuando creo otro level block y coloco los puntos de StartPoint y EndPoint no coinciden las posiciones x-y -z del 1ro con el 2do. Cuando coloco las mismas que el 1ro al segundo, se posiciona en una zona diferente a la que se supone. ¿Qué es lo que ocurre?
verifica los valores del transform del prefab
Tengo un problema con el codigo que se esta generando todo hacia abajo, y no hacia la derecha como se muestra el video, no se cual pueda ser el problema
Por que es necesario hacer que los bloques sean hijos de la clase LevelManager?.