Parte: 2 — Desarrollo 3D: motores, escenas y transformaciones · Fuente: Documentación oficial de Godot 4 — Using GridMaps y CSG tools ⏱️ Duración estimada: 60 min · Nivel: Intermedio
Aprender a construir niveles 3D de forma rápida y ordenada usando dos flujos complementarios: el blockout con nodos CSG para prototipar volúmenes y probar el diseño antes de invertir en arte, y el GridMap con una MeshLibrary para "pintar" niveles con piezas modulares reutilizables. Es el puente entre la idea y el nivel jugable.
Al terminar habrás bloqueado un pequeño nivel con CSGBox3D/CSGCombiner3D, habrás generado una MeshLibrary a partir de piezas simples y habrás pintado con GridMap una versión modular navegable de ese mismo espacio.
Al finalizar, el alumno podrá:
CSGBox3D, CSGCombiner3D y operaciones booleanas.MeshLibrary a partir de escenas o mallas para usarla como kit modular.GridMap usando esa librería y colisiones.| # | Tema | Por qué importa |
|---|---|---|
| 1 | Blockout / greybox | Permite validar el diseño sin gastar tiempo en arte. |
| 2 | Nodos CSG | Construyen y restan volúmenes rápidamente para prototipar. |
| 3 | Operaciones booleanas CSG | Unir, restar e intersecar crea huecos, puertas y pasillos. |
| 4 | MeshLibrary | Es el catálogo de piezas modulares que usa el GridMap. |
| 5 | GridMap | Coloca piezas en una rejilla 3D como un editor de tiles 3D. |
| 6 | Modularidad y escala | Piezas que encajan en la rejilla aceleran el montaje. |
| 7 | Flujo greybox → arte | Reemplazar piezas sin rehacer el nivel entero. |
subtraction abre huecos como puertas o ventanas.GridMap.MeshLibrary en una rejilla 3D de tamaño fijo. Clave: acelera enormemente construir niveles modulares.GridMap. Clave: debe coincidir con la escala de tus piezas modulares.Necesitas Godot 4.x desde https://godotengine.org/download. Las guías clave son "Using GridMaps" en https://docs.godotengine.org/en/stable/tutorials/3d/using_gridmaps.html y "Prototyping levels with CSG" en https://docs.godotengine.org/en/stable/tutorials/3d/csg_tools.html. Para exportar la librería revisa la sección de creación de MeshLibrary en la misma guía de GridMaps. Trabajaremos con cajas y mallas primitivas: el objetivo es el flujo, no el modelado.
Haremos primero un blockout con CSG y luego una versión modular con GridMap.
Crea una escena con raíz Node3D llamada Blockout, con Camera3D y DirectionalLight3D. Añade un CSGCombiner3D llamado Estructura.
Dentro de Estructura, añade un CSGBox3D grande y plano como suelo (por ejemplo size = Vector3(20, 1, 20)). Añade cuatro CSGBox3D verticales como muros perimetrales.
Para abrir una puerta en un muro, añade otro CSGBox3D que atraviese el muro y ponle Operation = Subtraction en el Inspector. El hueco aparecerá al instante: eso es el poder del CSG para prototipar.
Puedes ajustar todo por código desde Estructura para probar variantes de tamaño rápidamente:
extends CSGCombiner3D
func _ready() -> void:
# Genera un pasillo de N segmentos de muro por código para probar longitudes.
var largo := 6
for i in largo:
var muro := CSGBox3D.new()
muro.size = Vector3(1, 3, 4)
muro.position = Vector3(-5, 1.5, -i * 4)
add_child(muro)
print("Blockout generado con ", largo, " segmentos")
Crea una escena aparte por cada pieza modular (por ejemplo piso.tscn, muro.tscn). Cada una: un Node3D raíz con un MeshInstance3D (BoxMesh a escala de celda) y un StaticBody3D con CollisionShape3D para que el jugador no las atraviese. Diséñalas para una celda de 2×2×2.
Crea una escena Node3D llamada KitLibreria. Añade tus piezas como hijos instanciados. Con la raíz seleccionada, ve al menú Escena → Convertir en… → MeshLibrary y guárdala como kit.meshlib. Cada pieza queda numerada en la librería.
Crea la escena principal Node3D NivelModular con Camera3D y DirectionalLight3D. Añade un nodo GridMap. En su Inspector, asigna kit.meshlib a la propiedad Mesh Library y pon Cell → Size = (2, 2, 2) para que coincida con tus piezas.
Con el GridMap seleccionado, en el panel inferior aparece la paleta de piezas. Selecciona el "piso" y pinta una plataforma; selecciona el "muro" y levanta paredes alrededor. Estás construyendo el nivel como si fuera un editor de tiles, pero en 3D.
También puedes colocar celdas por código, útil para generación procedimental:
extends GridMap
func _ready() -> void:
# item 0 = piso, item 1 = muro (según el orden en la MeshLibrary).
var piso := 0
for x in range(-4, 5):
for z in range(-4, 5):
set_cell_item(Vector3i(x, 0, z), piso)
# Borde de muros en una fila.
var muro := 1
for x in range(-4, 5):
set_cell_item(Vector3i(x, 1, -4), muro)
MeshLibrary por arte final actualiza todas las celdas que la usan sin rehacer el mapa.CSGBox3D rotado) y comprueba el recorrido.Subtraction para abrir una ventana en un muro CSG.MeshLibrary y píntala en el GridMap.set_cell_item.cell_size a 4 y ajusta las piezas para que encajen; observa qué se rompe si no cuadran.Diseña una sala jugable en dos pasadas: primero un blockout completo con CSG (suelo, muros, una puerta por Subtraction y una rampa) y luego reconstruye esa misma sala con GridMap y una MeshLibrary de al menos 3 piezas, con colisiones funcionales. Criterio de aceptación: el blockout permite recorrer la sala y validar la puerta y la rampa; la versión GridMap reproduce el mismo espacio con piezas modulares que encajan sin huecos ni solapes, tiene colisión (el jugador no atraviesa muros) y al menos parte del mapa se pinta y otra parte se genera por código con set_cell_item.
| Síntoma / mensaje | Causa y cómo arreglar |
|---|---|
| La resta CSG no abre el hueco | El CSGBox3D a restar no es hijo del CSGCombiner3D o no está en modo Subtraction. Colócalo dentro y cambia Operation. |
| Las piezas del GridMap dejan huecos o se solapan | El cell_size no coincide con el tamaño de las piezas. Ajústalos para que encajen. |
| La paleta del GridMap aparece vacía | No asignaste una MeshLibrary válida a la propiedad Mesh Library. Asígnala. |
| El jugador atraviesa los muros del GridMap | Las piezas se exportaron sin StaticBody3D/CollisionShape3D. Añade colisión antes de generar la librería. |
| Cambiar una pieza no actualiza el nivel | Editaste una instancia, no la escena de la pieza o la librería. Regenera la MeshLibrary. |
| CSG lento con muchas operaciones | El CSG recalcula geometría; no lo uses para el nivel final, solo para blockout. |
❓ ¿Debo entregar el nivel final en CSG? No. El CSG es excelente para prototipar, pero recalcula geometría y no rinde bien a gran escala. Úsalo para el greybox y pasa a GridMap o mallas importadas para el nivel definitivo.
❓ ¿Por qué mis piezas no encajan en el GridMap? Porque su tamaño no es múltiplo del cell_size. Diseña las piezas a la medida exacta de la celda (o un múltiplo) para que la rejilla las alinee sin huecos.
❓ ¿Cómo añado colisión a las piezas del kit? Cada pieza debe incluir un StaticBody3D con su CollisionShape3D antes de convertir la escena en MeshLibrary. El GridMap conserva esa colisión.
❓ ¿Puedo mezclar GridMap con instancias sueltas? Sí. Lo habitual es usar GridMap para la estructura repetitiva (suelos, muros) e instanciar props únicos (coleccionables, enemigos) por código encima, como viste en la clase anterior.
Clase 064 - Instanciado y escenas 3D reutilizables
Clase 066 - Optimización 3D básica: LOD, occlusion y draw calls