Start dynamic sky
This commit is contained in:
399
dynamic-sky/scripts/dynamic_sky_root.gd
Normal file
399
dynamic-sky/scripts/dynamic_sky_root.gd
Normal file
@@ -0,0 +1,399 @@
|
||||
@tool
|
||||
class_name DynamicSkyRoot
|
||||
extends Node3D
|
||||
|
||||
signal time_of_day_changed(time: float)
|
||||
signal weather_changed(state: WeatherProfile.WeatherState)
|
||||
signal preset_changed(preset: SkyPreset)
|
||||
|
||||
@export_group("Controllers")
|
||||
@export var preset_library: SkyboxPresetLibrary
|
||||
@export var day_night_controller: DayNightController
|
||||
@export var weather_controller: WeatherController
|
||||
@export var cloud_system: CloudSystem2D
|
||||
@export var post_process_controller: PostProcessController
|
||||
@export var vfx_controller: VFXController
|
||||
@export var shadow_proxy_system: ShadowProxySystem
|
||||
|
||||
@export_group("Environment")
|
||||
@export var world_environment: WorldEnvironment
|
||||
@export var sun_light: DirectionalLight3D
|
||||
@export var moon_light: DirectionalLight3D
|
||||
|
||||
@export_group("Global Settings")
|
||||
@export var auto_create_controllers: bool = true
|
||||
@export var deterministic_seed: int = 0:
|
||||
set(value):
|
||||
deterministic_seed = value
|
||||
_apply_seed()
|
||||
|
||||
@export_group("Debug")
|
||||
@export var show_debug_panel: bool = false
|
||||
@export var debug_time_override: float = -1.0
|
||||
|
||||
var _current_config: SkyConfig
|
||||
var preset_name: String = ""
|
||||
var _updating_preset_name: bool = false
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
if auto_create_controllers:
|
||||
_ensure_controllers_exist()
|
||||
|
||||
_connect_signals()
|
||||
property_list_changed_notify()
|
||||
_sync_preset_name()
|
||||
_apply_seed()
|
||||
_sync_all_systems()
|
||||
|
||||
|
||||
func _process(delta: float) -> void:
|
||||
_sync_all_systems()
|
||||
|
||||
if show_debug_panel:
|
||||
_update_debug_info()
|
||||
|
||||
|
||||
func _ensure_controllers_exist() -> void:
|
||||
if preset_library == null:
|
||||
preset_library = SkyboxPresetLibrary.new()
|
||||
preset_library.name = "PresetLibrary"
|
||||
add_child(preset_library)
|
||||
|
||||
if day_night_controller == null:
|
||||
day_night_controller = DayNightController.new()
|
||||
day_night_controller.name = "DayNightController"
|
||||
add_child(day_night_controller)
|
||||
|
||||
if weather_controller == null:
|
||||
weather_controller = WeatherController.new()
|
||||
weather_controller.name = "WeatherController"
|
||||
add_child(weather_controller)
|
||||
|
||||
if cloud_system == null:
|
||||
cloud_system = CloudSystem2D.new()
|
||||
cloud_system.name = "CloudSystem"
|
||||
add_child(cloud_system)
|
||||
|
||||
if post_process_controller == null:
|
||||
post_process_controller = PostProcessController.new()
|
||||
post_process_controller.name = "PostProcessController"
|
||||
add_child(post_process_controller)
|
||||
|
||||
if vfx_controller == null:
|
||||
vfx_controller = VFXController.new()
|
||||
vfx_controller.name = "VFXController"
|
||||
add_child(vfx_controller)
|
||||
|
||||
if shadow_proxy_system == null:
|
||||
shadow_proxy_system = ShadowProxySystem.new()
|
||||
shadow_proxy_system.name = "ShadowProxySystem"
|
||||
add_child(shadow_proxy_system)
|
||||
|
||||
if world_environment == null:
|
||||
_create_default_environment()
|
||||
|
||||
if sun_light == null:
|
||||
_create_sun_light()
|
||||
|
||||
if moon_light == null:
|
||||
_create_moon_light()
|
||||
|
||||
|
||||
func _create_default_environment() -> void:
|
||||
world_environment = WorldEnvironment.new()
|
||||
world_environment.name = "WorldEnvironment"
|
||||
world_environment.environment = Environment.new()
|
||||
world_environment.environment.background_mode = Environment.BG_SKY
|
||||
world_environment.environment.sky = Sky.new()
|
||||
add_child(world_environment)
|
||||
|
||||
if post_process_controller:
|
||||
post_process_controller.target_environment = world_environment.environment
|
||||
|
||||
|
||||
func _create_sun_light() -> void:
|
||||
sun_light = DirectionalLight3D.new()
|
||||
sun_light.name = "SunLight"
|
||||
sun_light.light_color = Color(1.0, 0.95, 0.85)
|
||||
sun_light.light_energy = 1.0
|
||||
sun_light.shadow_enabled = true
|
||||
add_child(sun_light)
|
||||
|
||||
|
||||
func _create_moon_light() -> void:
|
||||
moon_light = DirectionalLight3D.new()
|
||||
moon_light.name = "MoonLight"
|
||||
moon_light.light_color = Color(0.7, 0.8, 1.0)
|
||||
moon_light.light_energy = 0.3
|
||||
moon_light.shadow_enabled = false
|
||||
add_child(moon_light)
|
||||
|
||||
|
||||
func _connect_signals() -> void:
|
||||
if day_night_controller:
|
||||
day_night_controller.time_changed.connect(_on_time_changed)
|
||||
|
||||
if weather_controller:
|
||||
weather_controller.weather_state_changed.connect(_on_weather_state_changed)
|
||||
|
||||
if preset_library:
|
||||
preset_library.preset_changed.connect(_on_preset_changed)
|
||||
|
||||
|
||||
func _on_time_changed(time: float) -> void:
|
||||
time_of_day_changed.emit(time)
|
||||
|
||||
if vfx_controller:
|
||||
vfx_controller.set_night_mode(day_night_controller.is_nighttime())
|
||||
|
||||
|
||||
func _on_weather_state_changed(old_state: WeatherProfile.WeatherState, new_state: WeatherProfile.WeatherState) -> void:
|
||||
weather_changed.emit(new_state)
|
||||
|
||||
|
||||
func _on_preset_changed(preset: SkyPreset) -> void:
|
||||
preset_changed.emit(preset)
|
||||
if preset.config:
|
||||
_current_config = preset.config
|
||||
_sync_preset_name()
|
||||
|
||||
_apply_preset_assets(preset)
|
||||
|
||||
|
||||
func _apply_seed() -> void:
|
||||
if deterministic_seed != 0:
|
||||
seed(deterministic_seed)
|
||||
|
||||
|
||||
func _sync_all_systems() -> void:
|
||||
if day_night_controller == null:
|
||||
return
|
||||
|
||||
var time := day_night_controller.time_of_day
|
||||
if debug_time_override >= 0:
|
||||
time = debug_time_override
|
||||
|
||||
_sync_sun_moon()
|
||||
_sync_clouds()
|
||||
_sync_post_process()
|
||||
_sync_shadows()
|
||||
|
||||
|
||||
func _sync_sun_moon() -> void:
|
||||
if day_night_controller == null:
|
||||
return
|
||||
|
||||
var sun_dir := day_night_controller.get_sun_direction()
|
||||
var moon_dir := day_night_controller.get_moon_direction()
|
||||
|
||||
if sun_light:
|
||||
sun_light.look_at(global_position - sun_dir, Vector3.UP)
|
||||
sun_light.light_color = day_night_controller.get_sun_color()
|
||||
sun_light.light_energy = day_night_controller.get_sun_intensity()
|
||||
sun_light.visible = day_night_controller.get_sun_intensity() > 0.01
|
||||
|
||||
if moon_light:
|
||||
moon_light.look_at(global_position - moon_dir, Vector3.UP)
|
||||
moon_light.light_color = day_night_controller.get_moon_color()
|
||||
moon_light.light_energy = day_night_controller.get_moon_intensity()
|
||||
moon_light.visible = day_night_controller.get_moon_intensity() > 0.01
|
||||
|
||||
if world_environment and world_environment.environment:
|
||||
world_environment.environment.ambient_light_color = day_night_controller.get_ambient_color()
|
||||
world_environment.environment.ambient_light_energy = day_night_controller.get_ambient_intensity()
|
||||
|
||||
|
||||
func _sync_clouds() -> void:
|
||||
if cloud_system == null:
|
||||
return
|
||||
|
||||
if day_night_controller:
|
||||
cloud_system.set_sun_lighting(
|
||||
day_night_controller.get_sun_direction(),
|
||||
day_night_controller.get_sun_color(),
|
||||
day_night_controller.get_sun_intensity()
|
||||
)
|
||||
cloud_system.set_moon_lighting(
|
||||
day_night_controller.get_moon_direction(),
|
||||
day_night_controller.get_moon_color(),
|
||||
day_night_controller.get_moon_intensity()
|
||||
)
|
||||
|
||||
if weather_controller:
|
||||
cloud_system.global_coverage = weather_controller.get_cloud_coverage()
|
||||
cloud_system.set_global_wind(
|
||||
weather_controller.get_wind_direction(),
|
||||
weather_controller.get_wind_speed()
|
||||
)
|
||||
|
||||
|
||||
func _sync_post_process() -> void:
|
||||
if post_process_controller == null or day_night_controller == null:
|
||||
return
|
||||
|
||||
var sun_dir := day_night_controller.get_sun_direction()
|
||||
var sun_color := day_night_controller.get_sun_color()
|
||||
|
||||
post_process_controller.set_sun_glow(
|
||||
sun_dir,
|
||||
sun_color,
|
||||
day_night_controller.get_sun_intensity() * 0.5,
|
||||
0.2
|
||||
)
|
||||
|
||||
post_process_controller.set_fog_settings(
|
||||
day_night_controller.get_fog_color(),
|
||||
day_night_controller.get_fog_density()
|
||||
)
|
||||
|
||||
var dawn_dusk_blend := 0.0
|
||||
if day_night_controller.is_dawn() or day_night_controller.is_dusk():
|
||||
dawn_dusk_blend = 1.0
|
||||
post_process_controller.set_dawn_dusk_blend(dawn_dusk_blend)
|
||||
|
||||
post_process_controller.set_stars_visibility(
|
||||
day_night_controller.get_stars_visibility()
|
||||
)
|
||||
|
||||
if _current_config:
|
||||
post_process_controller.set_sky_colors(
|
||||
_current_config.sky_top_color,
|
||||
_current_config.sky_horizon_color,
|
||||
_current_config.sky_bottom_color
|
||||
)
|
||||
post_process_controller.gradient_intensity = _current_config.gradient_intensity
|
||||
post_process_controller.apply_config(_current_config)
|
||||
|
||||
|
||||
func _apply_preset_assets(preset: SkyPreset) -> void:
|
||||
if preset == null:
|
||||
return
|
||||
|
||||
if post_process_controller:
|
||||
post_process_controller.skybox_texture = preset.skybox_texture
|
||||
if preset.post_process_profile:
|
||||
post_process_controller.profile = preset.post_process_profile
|
||||
|
||||
if cloud_system and preset.cloud_layer_configs.size() > 0:
|
||||
cloud_system.layer_configs = preset.cloud_layer_configs
|
||||
cloud_system.rebuild_layers()
|
||||
|
||||
|
||||
func _get_property_list() -> Array:
|
||||
var properties := []
|
||||
var names: PackedStringArray = []
|
||||
if preset_library:
|
||||
names = preset_library.get_preset_names()
|
||||
|
||||
var hint_string := ""
|
||||
if names.size() > 0:
|
||||
hint_string = ",".join(names)
|
||||
|
||||
properties.append({
|
||||
"name": "preset_name",
|
||||
"type": TYPE_STRING,
|
||||
"usage": PROPERTY_USAGE_EDITOR,
|
||||
"hint": PROPERTY_HINT_ENUM,
|
||||
"hint_string": hint_string,
|
||||
})
|
||||
return properties
|
||||
|
||||
|
||||
func _set(property: StringName, value: Variant) -> bool:
|
||||
if property == "preset_name":
|
||||
if preset_name == value:
|
||||
return true
|
||||
preset_name = value
|
||||
if _updating_preset_name:
|
||||
return true
|
||||
if preset_library and String(preset_name) != "":
|
||||
preset_library.apply_preset(String(preset_name))
|
||||
return true
|
||||
return false
|
||||
|
||||
|
||||
func _get(property: StringName) -> Variant:
|
||||
if property == "preset_name":
|
||||
return preset_name
|
||||
return null
|
||||
|
||||
|
||||
func _sync_preset_name() -> void:
|
||||
if preset_library == null:
|
||||
return
|
||||
var current := preset_library.get_current_preset()
|
||||
if current == null:
|
||||
return
|
||||
_updating_preset_name = true
|
||||
preset_name = current.preset_name
|
||||
_updating_preset_name = false
|
||||
|
||||
|
||||
func _sync_shadows() -> void:
|
||||
if shadow_proxy_system == null:
|
||||
return
|
||||
|
||||
if weather_controller:
|
||||
shadow_proxy_system.set_cloud_coverage(weather_controller.get_cloud_coverage())
|
||||
|
||||
if cloud_system:
|
||||
shadow_proxy_system.sync_with_cloud_system(cloud_system)
|
||||
|
||||
|
||||
func _update_debug_info() -> void:
|
||||
pass
|
||||
|
||||
|
||||
func set_time_of_day(time: float) -> void:
|
||||
if day_night_controller:
|
||||
day_night_controller.time_of_day = time
|
||||
|
||||
|
||||
func set_weather(state: WeatherProfile.WeatherState, transition_time: float = -1.0) -> void:
|
||||
if weather_controller:
|
||||
weather_controller.set_weather(state, transition_time)
|
||||
|
||||
|
||||
func apply_preset(preset_name: String) -> void:
|
||||
if preset_library:
|
||||
preset_library.apply_preset(preset_name)
|
||||
|
||||
|
||||
func pause_time() -> void:
|
||||
if day_night_controller:
|
||||
day_night_controller.paused = true
|
||||
|
||||
|
||||
func resume_time() -> void:
|
||||
if day_night_controller:
|
||||
day_night_controller.paused = false
|
||||
|
||||
|
||||
func trigger_meteor_shower(duration: float = 60.0) -> void:
|
||||
if vfx_controller:
|
||||
vfx_controller.start_meteor_shower(duration)
|
||||
|
||||
|
||||
func get_time_of_day() -> float:
|
||||
if day_night_controller:
|
||||
return day_night_controller.time_of_day
|
||||
return 0.0
|
||||
|
||||
|
||||
func get_current_weather() -> WeatherProfile.WeatherState:
|
||||
if weather_controller:
|
||||
return weather_controller.current_weather
|
||||
return WeatherProfile.WeatherState.CLEAR
|
||||
|
||||
|
||||
func is_daytime() -> bool:
|
||||
if day_night_controller:
|
||||
return day_night_controller.is_daytime()
|
||||
return true
|
||||
|
||||
|
||||
func is_nighttime() -> bool:
|
||||
if day_night_controller:
|
||||
return day_night_controller.is_nighttime()
|
||||
return false
|
||||
Reference in New Issue
Block a user