667 lines
25 KiB
GDScript
667 lines
25 KiB
GDScript
class_name WeatherController
|
|
extends Node
|
|
|
|
var thunder_audio_player: AudioStreamPlayer
|
|
var thunder_sounds: Array[AudioStream]
|
|
var rain_sounds: Array[AudioStream]
|
|
var rain_audio_player: AudioStreamPlayer
|
|
|
|
var particles_wind: GPUParticles3D
|
|
var particles_snow: GPUParticles3D
|
|
var particles_fireflies: GPUParticles3D
|
|
var particles_rain: GPUParticles3D
|
|
var godray: PackedScene
|
|
var environment_dust: ColorRect
|
|
var blur: ColorRect
|
|
var environment_shadows: MeshInstance3D
|
|
|
|
var sun: DirectionalLight3D
|
|
var environment: WorldEnvironment
|
|
var environment_config: EnvironmentConfig
|
|
var camera: Camera3D
|
|
var camera_pivot: Node3D
|
|
|
|
var day_time: float = 0.0
|
|
|
|
var lightning_sprite: Sprite3D
|
|
var lightning_light = DirectionalLight3D.new();
|
|
var timer_next_lightning: float = 0.0
|
|
|
|
var is_raining: bool = false
|
|
var rain_intensity: float = 0.0
|
|
var rain_tween: Tween
|
|
var rain_audio_tween: Tween
|
|
var puddle_tween: Tween
|
|
var puddle_amount: float = 0.0
|
|
|
|
var snow_tween: Tween
|
|
var snow_particles_tween: Tween
|
|
var is_snowing: bool = false
|
|
var is_snow_accumulated: bool = false
|
|
var actual_snow_amount: float = 0.0
|
|
|
|
var is_storm: bool = false
|
|
var cold_tween: Tween
|
|
var is_windy: bool = false
|
|
var thereare_fireflies: bool = false
|
|
|
|
func _init(wind: GPUParticles3D, snow: GPUParticles3D,
|
|
fireflies: GPUParticles3D, rain: GPUParticles3D, ray: PackedScene,
|
|
dust: ColorRect, blurr: ColorRect, envshadows: MeshInstance3D,
|
|
thesun: DirectionalLight3D, theenvironment: WorldEnvironment, environmentconfig: EnvironmentConfig,
|
|
thecamera: Camera3D, thecamerapivot: Node3D, thundersounds: Array[AudioStream], rainsounds: Array[AudioStream]) -> void:
|
|
particles_wind = wind
|
|
particles_snow = snow
|
|
particles_fireflies = fireflies
|
|
particles_rain = rain
|
|
godray = ray
|
|
sun = thesun
|
|
environment_dust = dust
|
|
blur = blurr
|
|
environment_shadows = envshadows
|
|
environment = theenvironment
|
|
environment_config = environmentconfig
|
|
camera = thecamera
|
|
camera_pivot = thecamerapivot
|
|
thunder_sounds = thundersounds
|
|
rain_sounds = rainsounds
|
|
|
|
set_rain()
|
|
|
|
set_fireflies()
|
|
|
|
set_wind()
|
|
|
|
set_snow()
|
|
|
|
set_lightning()
|
|
|
|
create_sound_players()
|
|
|
|
toggle_dust(environment_config.enable_dust)
|
|
toggle_blur(environment_config.enable_blur)
|
|
|
|
#set camera pivot if available
|
|
if camera_pivot:
|
|
camera_pivot.get_node("pivot").camera_changed.connect(_set_camera)
|
|
|
|
func _ready() -> void:
|
|
|
|
#connect events
|
|
UIEvents.toggle_rain.connect(toggle_rain)
|
|
UIEvents.toggle_snow.connect(toggle_snow)
|
|
UIEvents.toggle_wind.connect(toggle_wind)
|
|
UIEvents.toggle_fireflies.connect(toggle_fireflies)
|
|
UIEvents.toggle_storm.connect(toggle_storm)
|
|
UIEvents.toggle_dust.connect(toggle_dust)
|
|
UIEvents.toggle_blur.connect(toggle_blur)
|
|
UIEvents.toggle_shadows.connect(toggle_shadows)
|
|
|
|
func _process(delta: float) -> void:
|
|
|
|
_follow_camera()
|
|
|
|
var is_night = day_time >= 2.5
|
|
if particles_fireflies:
|
|
particles_fireflies.emitting = thereare_fireflies and is_night
|
|
|
|
var base_tint: Color
|
|
var base_sky_top: Color
|
|
var base_sky_horizon: Color
|
|
var base_fog_color: Color
|
|
var base_fog_density: float
|
|
var base_bloom: float
|
|
var base_exposure: float
|
|
var base_grad_top: Color
|
|
var base_grad_bot: Color
|
|
var base_grad_intensity: float
|
|
var base_rotation_sun: Vector3
|
|
|
|
if is_raining:
|
|
var target_rain = environment_config.storm_rain_intensity_multiplier if is_storm else 1.0
|
|
rain_intensity = move_toward(rain_intensity, target_rain, delta * 0.5)
|
|
if is_storm:
|
|
timer_next_lightning -= delta
|
|
if timer_next_lightning <= 0.0:
|
|
start_lightning()
|
|
set_lightning_timer()
|
|
else:
|
|
rain_intensity = move_toward(rain_intensity, 0.0, delta * 0.5)
|
|
|
|
RenderingServer.global_shader_parameter_set("global_rain_intensity", rain_intensity)
|
|
|
|
if day_time <= 2.0:
|
|
var t = day_time - 1.0
|
|
base_tint = environment_config.morning_color.lerp(environment_config.afternoon_color, t)
|
|
base_sky_top = environment_config.sky_top_morning.lerp(environment_config.sky_top_afternoon, t)
|
|
base_sky_horizon = environment_config.sky_horizon_morning.lerp(environment_config.sky_horizon_afternoon, t)
|
|
base_fog_color = environment_config.fog_color_morning.lerp(environment_config.fog_color_afternoon, t)
|
|
base_fog_density = lerp(environment_config.fog_density_morning, environment_config.fog_density_afternoon, t)
|
|
base_bloom = lerp(environment_config.glow_morning, environment_config.glow_afternoon, t)
|
|
base_exposure = lerp(environment_config.exposure_morning, environment_config.exposure_afternoon, t)
|
|
base_grad_top = environment_config.grad_top_morning.lerp(environment_config.grad_top_afternoon, t)
|
|
base_grad_bot = environment_config.grad_top_morning.lerp(environment_config.grad_bot_afternoon, t)
|
|
base_grad_intensity = lerp(environment_config.grad_intensity_morning, environment_config.grad_intensity_afternoon, t)
|
|
base_rotation_sun = environment_config.sun_rotation_morning.lerp(environment_config.sun_rotation_afternoon, t)
|
|
else:
|
|
var t = day_time - 2.0
|
|
base_tint = environment_config.afternoon_color.lerp(environment_config.night_color, t)
|
|
base_sky_top = environment_config.sky_top_afternoon.lerp(environment_config.sky_top_night, t)
|
|
base_sky_horizon = environment_config.sky_horizon_afternoon.lerp(environment_config.sky_horizon_night, t)
|
|
base_fog_color = environment_config.fog_color_afternoon.lerp(environment_config.fog_color_night, t)
|
|
base_fog_density = lerp(environment_config.fog_density_afternoon, environment_config.fog_density_night, t)
|
|
base_bloom = lerp(environment_config.glow_afternoon, environment_config.glow_night, t)
|
|
base_exposure = lerp(environment_config.exposure_afternoon, environment_config.exposure_night, t)
|
|
base_grad_top = environment_config.grad_top_afternoon.lerp(environment_config.grad_top_night, t)
|
|
base_grad_bot = environment_config.grad_bot_afternoon.lerp(environment_config.grad_bot_night, t)
|
|
base_grad_intensity = lerp(environment_config.grad_intensity_afternoon, environment_config.grad_intensity_night, t)
|
|
base_rotation_sun = environment_config.sun_rotation_afternoon.lerp(environment_config.sun_rotation_night, t)
|
|
|
|
var weather_color = environment_config.rain_mode_color
|
|
if is_storm:
|
|
var storm_blend = clamp((rain_intensity - 1.0) / (environment_config.storm_rain_intensity_multiplier - 1.0), 0.0, 1.0)
|
|
weather_color = weather_color.lerp(environment_config.storm_mode_color, storm_blend)
|
|
var final_tint = base_tint.lerp(base_tint * weather_color, clamp(rain_intensity, 0.0, 1.0))
|
|
var final_sky_top = base_sky_top.lerp(base_sky_top * weather_color, clamp(rain_intensity, 0.0, 1.0))
|
|
var final_sky_horizon = base_sky_horizon.lerp(base_sky_horizon * weather_color, clamp(rain_intensity, 0.0, 1.0))
|
|
var final_fog_color = base_fog_color.lerp(base_fog_color * weather_color, clamp(rain_intensity, 0.0, 1.0))
|
|
var final_fog_density = lerp(base_fog_density, base_fog_density * 4.0, clamp(rain_intensity, 0.0, 1.0))
|
|
|
|
final_tint = final_tint.lerp(final_tint * environment_config.snow_mode_color, actual_snow_amount)
|
|
final_sky_top = final_sky_top.lerp(final_sky_top * environment_config.snow_mode_color, actual_snow_amount)
|
|
final_sky_horizon = final_sky_horizon.lerp(final_sky_horizon * environment_config.snow_mode_color, actual_snow_amount)
|
|
final_fog_color = final_fog_color.lerp(final_fog_color * environment_config.snow_mode_color, actual_snow_amount)
|
|
|
|
#Shader parameters for global trunk_shader
|
|
var final_grad_top = base_grad_top.lerp(base_grad_top * weather_color, clamp(rain_intensity, 0.0, 1.0))
|
|
var final_grad_bot = base_grad_bot.lerp(base_grad_bot * weather_color, clamp(rain_intensity, 0.0, 1.0))
|
|
|
|
RenderingServer.global_shader_parameter_set("global_gradient_color_top", final_grad_top)
|
|
RenderingServer.global_shader_parameter_set("global_gradient_color_bot", final_grad_bot)
|
|
RenderingServer.global_shader_parameter_set("global_gradient_intensity", base_grad_intensity)
|
|
|
|
var night_val = clamp(day_time - 2.0, 0.0, 1.0)
|
|
|
|
#Snow exposure compensation
|
|
var snow_light_attenuation = lerp(1.0, 0.55, actual_snow_amount * (1.0 - night_val))
|
|
var snow_glow_attenuation = lerp(1.0, 0.5, actual_snow_amount)
|
|
var final_bloom = lerp(base_bloom, base_bloom * 0.5, rain_intensity) * snow_glow_attenuation
|
|
|
|
# We calculate the final exposure by applying snow damping directly to the camera exposure
|
|
var final_exposure = base_exposure * snow_light_attenuation
|
|
|
|
var reflected_color = Color(0.4, 0.5, 0.6, 1.0)
|
|
var drops_color = final_sky_horizon.lerp(reflected_color, 0.15)
|
|
drops_color = drops_color.lerp(drops_color * 0.4, night_val)
|
|
|
|
if environment_config.material_drops:
|
|
environment_config.material_drops.albedo_color = drops_color
|
|
|
|
if sun:
|
|
sun.light_color = final_tint
|
|
sun.rotation_degrees = base_rotation_sun
|
|
var target_energy = lerp(1.0, environment_config.night_light_energy, night_val)
|
|
|
|
# Sunlight scales based on weather/night
|
|
sun.light_energy = lerp(target_energy, target_energy * 0.4, rain_intensity)
|
|
|
|
if environment and environment.environment:
|
|
environment.environment.ambient_light_color = final_tint
|
|
|
|
# Apply fog
|
|
environment.environment.fog_enabled = true
|
|
environment.environment.fog_light_color = final_fog_color
|
|
environment.environment.fog_density = final_fog_density
|
|
|
|
# Apply glow
|
|
environment.environment.glow_enabled = true
|
|
environment.environment.glow_intensity = final_bloom
|
|
environment.environment.tonemap_exposure = final_exposure
|
|
|
|
var sky_mat = environment.environment.sky.sky_material as ShaderMaterial
|
|
if sky_mat:
|
|
sky_mat.set_shader_parameter("sky_top_color", final_sky_top)
|
|
sky_mat.set_shader_parameter("sky_horizon_color", final_sky_horizon)
|
|
sky_mat.set_shader_parameter("sun_color", final_tint)
|
|
sky_mat.set_shader_parameter("night_intensity", night_val)
|
|
|
|
if environment_config.material_clouds:
|
|
var current_density = lerp(0.4, 1.0, rain_intensity)
|
|
environment_config.material_clouds.set_shader_parameter("cloud_density", current_density)
|
|
var current_sharpness = lerp(0.14, 0.0, rain_intensity)
|
|
environment_config.material_clouds.set_shader_parameter("center_sharpness", current_sharpness)
|
|
|
|
if environment_config.material_fog:
|
|
environment_config.material_fog.set_shader_parameter("night_intensity", night_val)
|
|
environment_config.material_fog.set_shader_parameter("sun_color", final_tint)
|
|
|
|
func create_sound_players():
|
|
rain_audio_player = AudioStreamPlayer.new()
|
|
rain_audio_player.name = "RainAudioPlayer"
|
|
rain_audio_player.volume_db = environment_config.rain_audio_volume_db
|
|
rain_audio_player.finished.connect(_on_rain_audio_player_finished)
|
|
add_child(rain_audio_player)
|
|
|
|
thunder_audio_player = AudioStreamPlayer.new()
|
|
thunder_audio_player.name = "ThunderAudioPlayer"
|
|
thunder_audio_player.volume_db = environment_config.thunder_audio_volume_db
|
|
add_child(thunder_audio_player)
|
|
|
|
#region camera
|
|
func _set_camera(curr_camera: Camera3D):
|
|
camera = curr_camera
|
|
|
|
func _get_weather_anchor_position() -> Variant:
|
|
if camera_pivot and is_instance_valid(camera_pivot):
|
|
return camera_pivot.global_position
|
|
if camera and is_instance_valid(camera):
|
|
return camera.global_position
|
|
return null
|
|
|
|
func _follow_camera() -> void:
|
|
var cam_pos = _get_weather_anchor_position()
|
|
if cam_pos == null:
|
|
return
|
|
if particles_rain:
|
|
particles_rain.global_position = Vector3(cam_pos.x, particles_rain.position.y, cam_pos.z)
|
|
if particles_snow:
|
|
particles_snow.global_position = Vector3(cam_pos.x, particles_snow.position.y, cam_pos.z)
|
|
if particles_wind:
|
|
particles_wind.global_position = Vector3(cam_pos.x, cam_pos.y, cam_pos.z)
|
|
if particles_fireflies:
|
|
particles_fireflies.global_position = Vector3(cam_pos.x, particles_fireflies.position.y, cam_pos.z)
|
|
#endregion
|
|
|
|
#region Fireflies
|
|
|
|
func toggle_fireflies(value: bool):
|
|
thereare_fireflies = value
|
|
var is_night = day_time >= 2.5
|
|
if particles_fireflies:
|
|
particles_fireflies.emitting = thereare_fireflies and is_night
|
|
|
|
#disable fireflies and set default values and materials
|
|
func set_fireflies():
|
|
if particles_fireflies:
|
|
particles_fireflies.visible = true
|
|
particles_fireflies.emitting = false
|
|
particles_fireflies.amount = environment_config.fireflies_amount
|
|
var proc_mat = particles_fireflies.process_material as ParticleProcessMaterial
|
|
if proc_mat:
|
|
proc_mat.emission_box_extents = Vector3(environment_config.fireflies_spawn_ray, environment_config.fireflies_spawn_height, environment_config.fireflies_spawn_ray)
|
|
|
|
#endregion
|
|
|
|
#region Wind
|
|
|
|
func toggle_wind(value: bool):
|
|
is_windy = value
|
|
if particles_wind:
|
|
particles_wind.emitting = is_windy
|
|
|
|
#disable wind and set default values and materials
|
|
func set_wind():
|
|
if particles_wind:
|
|
particles_wind.visible = true
|
|
particles_wind.emitting = false
|
|
particles_wind.amount = environment_config.wind_amount
|
|
var proc_mat_wind = particles_wind.process_material as ParticleProcessMaterial
|
|
if proc_mat_wind:
|
|
proc_mat_wind.emission_box_extents = Vector3(environment_config.wind_spawn_ray, environment_config.wind_spawn_height, environment_config.wind_spawn_ray)
|
|
|
|
if environment_config:
|
|
_apply_cloud_config()
|
|
_apply_wind_config()
|
|
|
|
func _apply_wind_config() -> void:
|
|
RenderingServer.global_shader_parameter_set("global_wind_speed", environment_config.wind_speed)
|
|
RenderingServer.global_shader_parameter_set("global_wind_direction", environment_config.wind_direction)
|
|
RenderingServer.global_shader_parameter_set("global_wind_scale", environment_config.wind_scale)
|
|
RenderingServer.global_shader_parameter_set("global_wind_strength", environment_config.wind_strength)
|
|
if particles_wind:
|
|
var proc_mat_wind = particles_wind.process_material as ParticleProcessMaterial
|
|
if proc_mat_wind:
|
|
var wind_direction_3d := Vector3(environment_config.wind_direction.x, 0.0, environment_config.wind_direction.y)
|
|
if wind_direction_3d.length_squared() > 0.0:
|
|
var wind_axis := wind_direction_3d.normalized()
|
|
var wind_cross := wind_axis.cross(Vector3.UP)
|
|
if wind_cross.length_squared() == 0.0:
|
|
wind_cross = Vector3.FORWARD
|
|
else:
|
|
wind_cross = wind_cross.normalized()
|
|
var wind_up := wind_cross.cross(wind_axis).normalized()
|
|
proc_mat_wind.direction = wind_axis
|
|
particles_wind.global_transform = Transform3D(Basis(wind_cross, wind_axis, wind_up), particles_wind.global_position)
|
|
|
|
func _apply_cloud_config() -> void:
|
|
var dir = environment_config.wind_direction
|
|
var cloud_scale = environment_config.cloud_scale
|
|
var cloud_speed = environment_config.cloud_speed
|
|
var envshadows_scale_rate = environment_config.cloud_scale_envshadows_rate
|
|
var envshadows_speed_rate = environment_config.cloud_speed_envshadows_rate
|
|
|
|
if environment and environment.environment and environment.environment.sky:
|
|
var sky_mat = environment.environment.sky.sky_material as ShaderMaterial
|
|
if sky_mat:
|
|
sky_mat.set_shader_parameter("cloud_direction", dir)
|
|
sky_mat.set_shader_parameter("cloud_scale", cloud_scale)
|
|
sky_mat.set_shader_parameter("cloud_speed", cloud_speed)
|
|
|
|
var env_shadow_mat = environment_shadows.get_surface_override_material(0) if environment_shadows else null
|
|
if env_shadow_mat:
|
|
env_shadow_mat.set_shader_parameter("direction", dir)
|
|
env_shadow_mat.set_shader_parameter("cloud_scale", cloud_scale * envshadows_scale_rate)
|
|
env_shadow_mat.set_shader_parameter("cloud_speed", cloud_speed * envshadows_speed_rate)
|
|
|
|
if environment_config.material_clouds:
|
|
environment_config.material_clouds.set_shader_parameter("direction", dir)
|
|
environment_config.material_clouds.set_shader_parameter("cloud_scale", cloud_scale * envshadows_scale_rate)
|
|
environment_config.material_clouds.set_shader_parameter("cloud_speed", cloud_speed * envshadows_speed_rate)
|
|
|
|
#endregion
|
|
|
|
#region Lightning
|
|
|
|
func toggle_storm(value: bool):
|
|
is_storm = value
|
|
|
|
#set lightning
|
|
func set_lightning():
|
|
lightning_light.name = "Lightning Light"
|
|
lightning_light.transform = Transform3D(
|
|
Vector3(-0.6238797, -0.342596, 0.7024259), # asse X
|
|
Vector3(0.0, 0.89879405, 0.43837115), # asse Y
|
|
Vector3(-0.7815204, 0.27349085, -0.56073934), # asse Z
|
|
Vector3(0.0, 0.0, 30.411049) # origine
|
|
)
|
|
|
|
lightning_light.light_color = Color(0.8, 1.0, 1.0, 1.0)
|
|
lightning_light.light_energy = 0.0
|
|
lightning_light.shadow_enabled = true
|
|
add_child(lightning_light)
|
|
|
|
create_lightning_sprite()
|
|
set_lightning_timer()
|
|
|
|
func create_lightning_sprite():
|
|
lightning_sprite = Sprite3D.new()
|
|
lightning_sprite.name = "Lightning Sprite"
|
|
|
|
lightning_sprite.transform = Transform3D(
|
|
Basis(
|
|
Vector3(4, 0, 0),
|
|
Vector3(0, 7.32, 0),
|
|
Vector3(0, 0, 7.3)
|
|
),
|
|
Vector3(0, 17.324, 30.411049)
|
|
)
|
|
|
|
lightning_sprite.modulate = Color(1, 1, 1, 0)
|
|
lightning_sprite.billboard = BaseMaterial3D.BILLBOARD_ENABLED
|
|
lightning_sprite.alpha_cut = SpriteBase3D.ALPHA_CUT_DISCARD
|
|
|
|
#Add Texture
|
|
lightning_sprite.texture = load(environment_config.lightning_texture)
|
|
|
|
add_child(lightning_sprite)
|
|
|
|
#set next lightning timer
|
|
func set_lightning_timer():
|
|
timer_next_lightning = randf_range(environment_config.lightning_min_time, environment_config.lightning_max_time)
|
|
|
|
func start_lightning():
|
|
if lightning_light:
|
|
var tween_lighting = create_tween()
|
|
lightning_light.light_energy = 5.0
|
|
|
|
tween_lighting.tween_interval(0.05)
|
|
tween_lighting.tween_callback(func(): lightning_light.light_energy = 0.0)
|
|
tween_lighting.tween_interval(0.05)
|
|
tween_lighting.tween_callback(func(): lightning_light.light_energy = 2.0)
|
|
tween_lighting.tween_method(func(val): lightning_light.light_energy = val, 2.0, 0.0, 0.2)
|
|
|
|
var lightning_number = randi_range(environment_config.lightning_min, environment_config.lightning_max)
|
|
|
|
for i in lightning_number:
|
|
if lightning_sprite:
|
|
var random_angle = randf() * TAU
|
|
var distance = randf_range(10.0, 40.0)
|
|
|
|
lightning_sprite.position = Vector3(cos(random_angle) * distance, 10.0, sin(random_angle) * distance)
|
|
|
|
lightning_sprite.modulate = environment_config.lightning_color
|
|
lightning_sprite.modulate.a = 1.0
|
|
|
|
var s = randf_range(environment_config.lightning_scale_min, environment_config.lightning_scale_max)
|
|
lightning_sprite.scale = Vector3(s, s, s)
|
|
|
|
var tween_sprite = create_tween()
|
|
tween_sprite.tween_interval(0.2)
|
|
tween_sprite.tween_property(lightning_sprite, "modulate:a", 0.0, 0.4)
|
|
|
|
#Thunder sound; separated routine to do not stop the loop
|
|
_play_thunder_delayed(randf_range(0.5, 2.5))
|
|
|
|
if lightning_number > 1:
|
|
await get_tree().create_timer(randf_range(0.05, 0.15)).timeout
|
|
|
|
func _play_thunder_delayed(delay: float):
|
|
await get_tree().create_timer(delay).timeout
|
|
|
|
if thunder_sounds.is_empty() or not thunder_audio_player:
|
|
return
|
|
|
|
thunder_audio_player.stream = thunder_sounds[randi() % thunder_sounds.size()]
|
|
thunder_audio_player.pitch_scale = randf_range(0.9, 1.1)
|
|
thunder_audio_player.play()
|
|
|
|
#endregion
|
|
|
|
#region Rain
|
|
|
|
#disable rain
|
|
func set_rain():
|
|
if particles_rain:
|
|
particles_rain.visible = true
|
|
particles_rain.emitting = false
|
|
if rain_audio_player:
|
|
rain_audio_player.volume_db = environment_config.rain_audio_volume_db
|
|
rain_audio_player.stop()
|
|
RenderingServer.global_shader_parameter_set("global_rain_puddle_amount", 0.0)
|
|
|
|
func set_puddle_amount(value: float):
|
|
puddle_amount = value
|
|
RenderingServer.global_shader_parameter_set("global_rain_puddle_amount", value)
|
|
|
|
func toggle_rain(value: bool):
|
|
is_raining = value
|
|
|
|
if not particles_rain:
|
|
return
|
|
|
|
if is_raining and is_snowing:
|
|
toggle_snow(false)
|
|
|
|
if rain_tween and rain_tween.is_valid():
|
|
rain_tween.kill()
|
|
|
|
if puddle_tween and puddle_tween.is_valid():
|
|
puddle_tween.kill()
|
|
|
|
if is_raining:
|
|
particles_rain.amount_ratio = 0.0
|
|
particles_rain.emitting = true
|
|
if rain_audio_player:
|
|
if not rain_audio_player.playing:
|
|
rain_audio_player.volume_db = -80.0
|
|
_play_random_rain_sound()
|
|
_fade_rain_audio(environment_config.rain_audio_volume_db, false)
|
|
rain_tween = create_tween()
|
|
rain_tween.tween_property(particles_rain, "amount_ratio", 1.0, environment_config.rain_fade_time)
|
|
puddle_tween = create_tween()
|
|
puddle_tween.tween_method(set_puddle_amount, puddle_amount, 1.0, environment_config.puddle_form_time)
|
|
else:
|
|
if rain_audio_player:
|
|
_fade_rain_audio(-80.0, true)
|
|
rain_tween = create_tween()
|
|
rain_tween.tween_property(particles_rain, "amount_ratio", 0.0, environment_config.rain_fade_time)
|
|
rain_tween.tween_callback(func():
|
|
particles_rain.emitting = false
|
|
trigger_after_rain())
|
|
puddle_tween = create_tween()
|
|
puddle_tween.tween_method(set_puddle_amount, puddle_amount, 0.0, environment_config.puddle_dry_time)
|
|
|
|
func trigger_morning() -> void:
|
|
spawn_single_godray()
|
|
|
|
func trigger_after_rain() -> void:
|
|
if day_time < 2.5:
|
|
var count: int = randi_range(1, environment_config.godray_max_rain)
|
|
for i in count:
|
|
spawn_single_godray()
|
|
|
|
func spawn_single_godray() -> void:
|
|
var ray: Node3D = godray.instantiate()
|
|
get_tree().current_scene.add_child(ray)
|
|
|
|
var random_x: float = randf_range(-environment_config.godray_spawn_radius, environment_config.godray_spawn_radius)
|
|
var random_z: float = randf_range(-environment_config.godray_spawn_radius, environment_config.godray_spawn_radius)
|
|
|
|
var center := Vector3.ZERO
|
|
var anchor_pos = _get_weather_anchor_position()
|
|
if anchor_pos != null:
|
|
center = anchor_pos
|
|
ray.global_position = Vector3(center.x + random_x, environment_config.godray_spawn_height, center.z + random_z)
|
|
if ray.has_method("set_visual_rotation_degrees"):
|
|
ray.call("set_visual_rotation_degrees", environment_config.godray_rotation_degrees)
|
|
else:
|
|
ray.rotation_degrees = environment_config.godray_rotation_degrees
|
|
if ray.has_method("set_visual_scale"):
|
|
ray.call("set_visual_scale", environment_config.godray_scale)
|
|
else:
|
|
ray.scale = environment_config.godray_scale
|
|
if ray.has_method("orient_to_camera"):
|
|
ray.call("orient_to_camera")
|
|
|
|
func _play_random_rain_sound() -> void:
|
|
if rain_sounds.is_empty() or rain_audio_player == null:
|
|
return
|
|
|
|
rain_audio_player.stream = rain_sounds[randi() % rain_sounds.size()]
|
|
rain_audio_player.pitch_scale = 1.0
|
|
rain_audio_player.volume_db = minf(rain_audio_player.volume_db, environment_config.rain_audio_volume_db)
|
|
rain_audio_player.play()
|
|
|
|
func _on_rain_audio_player_finished() -> void:
|
|
if is_raining:
|
|
_play_random_rain_sound()
|
|
|
|
func _fade_rain_audio(target_volume_db: float, stop_after_fade: bool) -> void:
|
|
if rain_audio_player == null:
|
|
return
|
|
|
|
if rain_audio_tween and rain_audio_tween.is_valid():
|
|
rain_audio_tween.kill()
|
|
|
|
rain_audio_tween = create_tween()
|
|
rain_audio_tween.tween_property(
|
|
rain_audio_player,
|
|
"volume_db",
|
|
target_volume_db,
|
|
environment_config.rain_fade_time #same value of the rain particles
|
|
)
|
|
if stop_after_fade:
|
|
rain_audio_tween.tween_callback(func(): rain_audio_player.stop())
|
|
|
|
#endregion
|
|
|
|
#region Snow
|
|
|
|
func toggle_snow(value: bool):
|
|
is_snowing = value
|
|
|
|
if is_snowing and is_raining:
|
|
toggle_rain(false)
|
|
|
|
# Fade particelle neve
|
|
if particles_snow:
|
|
if snow_particles_tween and snow_particles_tween.is_valid():
|
|
snow_particles_tween.kill()
|
|
|
|
if is_snowing:
|
|
particles_snow.amount_ratio = 0.0
|
|
particles_snow.visible = true
|
|
particles_snow.emitting = true
|
|
snow_particles_tween = create_tween()
|
|
snow_particles_tween.tween_property(particles_snow, "amount_ratio", 1.0, environment_config.snow_fade_time)
|
|
|
|
start_snow_accumulation()
|
|
else:
|
|
snow_particles_tween = create_tween()
|
|
snow_particles_tween.tween_property(particles_snow, "amount_ratio", 0.0, environment_config.snow_fade_time)
|
|
snow_particles_tween.tween_callback(func():
|
|
particles_snow.emitting = false)
|
|
start_snow_melt()
|
|
|
|
var target_snow_amount: float = 1.0 if is_snowing else 0.0
|
|
if snow_tween and snow_tween.is_valid():
|
|
snow_tween.kill()
|
|
snow_tween = create_tween()
|
|
snow_tween.tween_method(set_snow_amount, actual_snow_amount, target_snow_amount, environment_config.snow_transaction_time)
|
|
|
|
#disable snow and set default values and shader
|
|
func set_snow(value: float = 0.0):
|
|
actual_snow_amount = value
|
|
RenderingServer.global_shader_parameter_set("global_snow_amount", value)
|
|
|
|
if particles_snow:
|
|
particles_snow.emitting = false
|
|
|
|
if environment_config:
|
|
RenderingServer.global_shader_parameter_set("global_snow_threshold", environment_config.snow_threshold)
|
|
RenderingServer.global_shader_parameter_set("global_snow_color", environment_config.snow_color)
|
|
RenderingServer.global_shader_parameter_set("global_snow_accumulation_speed", environment_config.snow_accumulation_speed)
|
|
RenderingServer.global_shader_parameter_set("global_snow_melt_speed", environment_config.snow_melt_speed)
|
|
RenderingServer.global_shader_parameter_set("global_snow_start_time", -1.0)
|
|
RenderingServer.global_shader_parameter_set("global_snow_melt_time", -1.0)
|
|
|
|
func set_snow_amount(value: float):
|
|
actual_snow_amount = value
|
|
RenderingServer.global_shader_parameter_set("global_snow_amount", value)
|
|
|
|
func start_snow_accumulation() -> void:
|
|
RenderingServer.global_shader_parameter_set("global_snow_melt_time", -1.0)
|
|
RenderingServer.global_shader_parameter_set("global_snow_start_time", Time.get_ticks_msec() / 1000.0)
|
|
|
|
func start_snow_melt() -> void:
|
|
RenderingServer.global_shader_parameter_set("global_snow_melt_time", Time.get_ticks_msec() / 1000.0)
|
|
RenderingServer.global_shader_parameter_set("global_snow_melt_speed", environment_config.snow_melt_speed)
|
|
|
|
#endregion
|
|
|
|
#region Post-Process
|
|
|
|
func toggle_dust(value: bool) -> void:
|
|
if environment_dust:
|
|
environment_dust.visible = value
|
|
|
|
func toggle_blur(value: bool) -> void:
|
|
if blur:
|
|
blur.visible = value
|
|
|
|
ApplyPostProcessBlurConfig()
|
|
|
|
func toggle_shadows(value: bool) -> void:
|
|
if environment_shadows:
|
|
environment_shadows.visible = value
|
|
|
|
func ApplyPostProcessBlurConfig() -> void:
|
|
if blur == null:
|
|
return
|
|
|
|
var blur_material := blur.material as ShaderMaterial
|
|
if blur_material:
|
|
blur_material.set_shader_parameter("blur_amount", environment_config.blur_amount)
|
|
|
|
#endregion
|