Creando un Sistema de Clima y Ciclo Día-Noche Dinámico en Godot 4
Descubre cómo dotar de vida a tus mundos virtuales implementando un sistema dinámico que alterne entre día y noche, además de generar efectos climáticos como lluvia, niebla y cambios de iluminación ambiental en Godot 4.
Introducción al Clima y Tiempo Dinámico 🌅
Crear un mundo inmersivo en el desarrollo de videojuegos va mucho más allá de diseñar niveles estáticos y personajes detallados. Uno de los elementos más impactantes para la inmersión del jugador es la simulación del paso del tiempo y las condiciones atmosféricas cambiantes. En este tutorial completo, aprenderás a construir desde cero un sistema robusto de ciclo día-noche y clima dinámico utilizando Godot 4.
1. Planificación de la Arquitectura del Sistema 🏗️
Antes de escribir una sola línea de código, necesitamos entender cómo se comunicarán los diferentes componentes de nuestro sistema. Tendremos un nodo central (el "Director del Tiempo") que llevará el conteo de los minutos y horas dentro del juego, y notificará a otros sistemas (como la iluminación global, las partículas de lluvia y el cielo) sobre los cambios de estado.
2. Creando el Gestor de Tiempo (TimeManager) ⏱️
El primer componente esencial es el script que calculará el paso del tiempo. Vamos a crear un nodo de tipo Node llamado TimeManager y le asignaremos un script en GDScript. Este script mantendrá variables para los minutos, horas y días del juego, acelerando el paso del tiempo real para que un ciclo completo ocurra en pocos minutos.
Abre Godot 4, crea una nueva escena con un nodo raíz Node, llámalo TimeManager y añade el siguiente código:
extends Node
class_name TimeManager
@export var minutes_per_game_day: float = 10.0
var time_elapsed: float = 0.0
var current_minute: int = 0
var current_hour: int = 6
var current_day: int = 1
signal time_changed(hour: int, minute: int)
signal day_changed(day: int)
func _process(delta: float):
var time_scale = (24.0 * 60.0) / (minutes_per_game_day * 60.0)
time_elapsed += delta * time_scale
var total_minutes = int(time_elapsed)
current_minute = total_minutes % 60
current_hour = (total_minutes / 60) % 24
var new_day = (total_minutes / (60 * 24)) + 1
if new_day != current_day:
current_day = new_day
emit_signal("day_changed", current_day)
emit_signal("time_changed", current_hour, current_minute)
minutes_per_game_day desde el inspector, podrás decidir exactamente cuánto dura un día completo en tu juego (por defecto, 10 minutos reales).3. Configurando la Iluminación Global y el Cielo 🌤️
Para que la iluminación del mapa cambie a medida que pasan las horas, necesitamos manipular un nodo DirectionalLight3D (que simula el sol) y un recurso WorldEnvironment que controle el ambiente y el color del cielo.
Asegúrate de tener en tu escena principal:
- Un
DirectionalLight3DllamadoSun. - Un
WorldEnvironmentcon un entorno configurado en modo ProceduralSky.
Ahora crearemos un script controlador que escuche las señales del TimeManager y mueva el sol en función de la hora actual:
extends Node3D
@export var sun: DirectionalLight3D
@export var world_environment: WorldEnvironment
func _ready():
var time_manager = get_node("/root/TimeManager")
if time_manager:
time_manager.connect("time_changed", Callable(self, "_on_time_changed"))
func _on_time_changed(hour: int, minute: int):
var total_minutes = hour * 60 + minute
var day_fraction = float(total_minutes) / (24.0 * 60.0)
# Rotar el sol 360 grados a lo largo del día
var sun_angle = day_fraction * 360.0 - 90.0
sun.rotation_degrees.x = sun_angle
# Ajustar la intensidad de la luz según la hora (noche = 0, mediodía = 1)
if hour >= 6 and hour <= 18:
sun.light_energy = sin(day_fraction * PI * 2) * 1.5
sun.visible = true
else:
sun.light_energy = 0.0
sun.visible = false
4. Implementando el Sistema de Clima Dinámico (Lluvia y Niebla) 🌧️
Un ciclo de tiempo realista no está completo sin variaciones atmosféricas. Vamos a programar un generador de clima aleatorio que active o desactive la lluvia y ajuste la densidad de la niebla en el WorldEnvironment.
Crea un nuevo script llamado WeatherController.gd:
extends Node
@export var rain_particles: GPUParticles3D
@export var world_environment: WorldEnvironment
enum WeatherType { CLEAR, RAIN, FOG }
var current_weather: WeatherType = WeatherType.CLEAR
func _ready():
var timer = Timer.new()
timer.wait_time = 60.0 # Cambia de clima cada minuto real
timer.autostart = true
timer.connect("timeout", Callable(self, "_change_weather_randomly"))
add_child(timer)
func _change_weather_randomly():
var random_roll = randi() % 3
current_weather = random_roll as WeatherType
var environment = world_environment.environment
match current_weather:
WeatherType.CLEAR:
rain_particles.emitting = false
environment.fog_enabled = false
print("Clima cambiado a: Despejado")
WeatherType.RAIN:
rain_particles.emitting = true
environment.fog_enabled = true
environment.fog_density = 0.01
print("Clima cambiado a: Lluvia")
WeatherType.FOG:
rain_particles.emitting = false
environment.fog_enabled = true
environment.fog_density = 0.05
print("Clima cambiado a: Niebla densa")
5. Comparativa de Estados Climáticos y Lumínicos 📊
Para ayudarte a calibrar los valores de tu entorno, aquí tienes una tabla de referencia rápida con los parámetros recomendados para diferentes momentos y climas:
| Condición | Hora del Día | Intensidad del Sol | Densidad de Niebla | Partículas Activas |
|---|---|---|---|---|
| --- | --- | --- | --- | --- |
| Mediodía Soleado | 12:00 | 1.5 | 0.00 (Desactivada) | Ninguna |
| Atardecer | 19:00 | 0.3 | 0.01 | Ninguna |
| --- | --- | --- | --- | --- |
| Noche Estrellada | 02:00 | 0.0 | 0.02 | Ninguna |
| Lluvia Torrencial | 14:00 | 0.8 | 0.03 | Lluvia Intensa |
6. Preguntas Frecuentes (FAQ) 🙋♂️
¿Cómo puedo hacer que las luces de las farolas se enciendan automáticamente de noche?
Puedes conectar un script a tus luces artificiales que escuche la señaltime_changed del TimeManager. Si la hora es mayor a 19:00 o menor a 6:00, cambias la propiedad visible = true de la luz.
¿Afecta el rendimiento tener partículas de lluvia activas todo el tiempo?
Godot 4 maneja las partículas mediante la GPU gracias a los nodosGPUParticles3D, lo cual es sumamente eficiente. Siempre y cuando ajustes el conteo máximo de partículas a un rango razonable (ej. 2000-5000), el impacto en FPS será mínimo.
Conclusión y Próximos Pasos 🎯
¡Felicidades! Has implementado con éxito un sistema completo de ciclo día-noche y clima dinámico en Godot 4. Este sistema transforma radicalmente la atmósfera de cualquier videojuego, aportando realismo y profundidad.
Como siguientes pasos recomendados, puedes:
- Añadir sonidos ambientales que cambien según la lluvia o la hora del día.
- Integrar efectos en el post-procesado como aberración cromática o viñeta durante las tormentas.
- Sincronizar este reloj con las rutinas de IA de tus personajes no jugables (NPCs).
Tutoriales relacionados
- Creando un Sistema de Menús Interactivos y Transiciones en Godot 4: UI Fluida para tu Juegointermediate18 min
- Creando un Sistema de Habilidades (Skills) y Árbol de Talentos en Godot 4intermediate15 min
- Creando Cinemáticas Impactantes con Secuencias de Animación en Godot 4intermediate15 min
- Navegación entre Escenas y Gestión de Estado en Godot 4: Creando un Flujo de Juego Dinámicointermediate15 min
- Creando un Sistema de Detección de Colisiones Avanzado en Godot 4: Precisión y Respuestaintermediate18 min
Comentarios (0)
Aún no hay comentarios. ¡Sé el primero!