tutoriales.com

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.

Intermedio8 min de lectura11 views
Reportar error

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.

💡 Consejo: Este sistema es altamente escalable y se puede adaptar tanto a proyectos en 2D como en entornos 3D, aunque nos enfocaremos en los conceptos lógicos de control mediante GDScript y nodos de iluminación.

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.

TimeManager Motor de Cronología WorldEnvironment Iluminación Global Capa de Cielo WeatherController Simulación de Lluvia Gestión de Niebla UI_Clock Visualización HUD Formato 24h / AM-PM
Paso 1: Crear el gestor lógico de tiempo (GDScript).
Paso 2: Configurar el entorno visual con WorldEnvironment y DirectionalLight3D.
Paso 3: Programar la transición de colores del cielo y la intensidad lumínica.
Paso 4: Implementar efectos climáticos (lluvia y partículas).

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)
📌 Nota: Modificando la variable exportada 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 DirectionalLight3D llamado Sun.
  • Un WorldEnvironment con 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")
⚠️ Advertencia: Asegúrate de que las partículas de lluvia estén posicionadas correctamente por encima del jugador y sigan su posición para evitar que la lluvia aparezca solo en un punto fijo del mapa.

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ónHora del DíaIntensidad del SolDensidad de NieblaPartículas Activas
---------------
Mediodía Soleado12:001.50.00 (Desactivada)Ninguna
Atardecer19:000.30.01Ninguna
---------------
Noche Estrellada02:000.00.02Ninguna
Lluvia Torrencial14:000.80.03Lluvia 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ñal time_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 nodos GPUParticles3D, 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

Comentarios (0)

Aún no hay comentarios. ¡Sé el primero!