class_name EnvironmentManagerRoot extends Node3D @export var environment_config: EnvironmentConfig @export_group("Camera") @export var camera: Camera3D @export_group("Particles") @export var particles_wind: GPUParticles3D @export var particles_snow: GPUParticles3D @export var particles_fireflies: GPUParticles3D @export var particles_rain: GPUParticles3D @export var godray: PackedScene @export var environment_dust: ColorRect @export var blur: ColorRect @export var environment_shadows: MeshInstance3D @export_group("Sound") @export var thunder_sounds: Array[AudioStream] #environment nodes @onready var sun: DirectionalLight3D = $"../DirectionalLight3D" @onready var environment: WorldEnvironment = $"../WorldEnvironment" @onready var audio_player: AudioStreamPlayer3D = $AudioStreamPlayer3D var day_night_controller: DayNightController var weather_controller: WeatherController var day_tween: Tween var day_time: float = 0.0 func _ready() -> void: #set noise texture 2d to materials in special group ApplyWindNoiseToMaterials() #set weather overlay (snow + rain) to materials in special group ApplyWeatherShaderToMaterials() if day_night_controller == null: day_night_controller = DayNightController.new( environment_config ) day_night_controller.name = "DayNightController" day_night_controller.time_changed.connect(select_day_time) add_child(day_night_controller) if weather_controller == null: weather_controller = WeatherController.new( particles_wind, particles_snow, particles_fireflies, particles_rain, godray, environment_dust, blur, environment_shadows, sun, environment, environment_config, camera, audio_player, thunder_sounds ) weather_controller.name = "WeatherController" add_child(weather_controller) func ApplyWindNoiseToMaterials(): var noise_tex = preload("res://core/daynight/noise.tres") for node in get_tree().get_nodes_in_group("wind_materials"): if node is GeometryInstance3D: node.material_override.set_shader_parameter("wind_noise", noise_tex) func ApplyWeatherShaderToMaterials(): var weather_shader = preload("res://core/daynight/weather_overlay.tres") for node in get_tree().get_nodes_in_group("weather_materials"): if node is GeometryInstance3D: node.material_overlay = weather_shader else: for child in node.get_children(): if child is GeometryInstance3D: child.material_overlay = weather_shader func select_day_time(normalized_time: float) -> void: # 0.0→0.25 = alba: day_time 1.0→2.0 (night colors → morning colors) # 0.25→0.5 = giorno: day_time 2.0→2.0 (stays morning/afternoon) # 0.5→0.75 = tramonto: day_time 2.0→3.0 (afternoon colors → night colors) # 0.75→1.0 = notte: day_time 3.0→3.0 (stays night) # At wrap 1.0→0.0: day_time stays 3.0, then fades back via alba if normalized_time < 0.25: # Alba: notte → mattina day_time = 3.0 - (normalized_time / 0.25) * 2.0 # 3.0 → 1.0 elif normalized_time < 0.5: # Giorno pieno var t: float = (normalized_time - 0.25) / 0.25 day_time = 1.0 + t # 1.0 → 2.0 elif normalized_time < 0.75: # Tramonto: pomeriggio → notte var t: float = (normalized_time - 0.5) / 0.25 day_time = 2.0 + t # 2.0 → 3.0 else: # Notte piena day_time = 3.0 if weather_controller: weather_controller.day_time = day_time