Added basic day night cycle
This commit is contained in:
@@ -66,6 +66,7 @@ cast_shadow = 0
|
|||||||
mesh = SubResource("ArrayMesh_q3k88")
|
mesh = SubResource("ArrayMesh_q3k88")
|
||||||
|
|
||||||
[node name="DirectionalLight3D" type="DirectionalLight3D" parent="."]
|
[node name="DirectionalLight3D" type="DirectionalLight3D" parent="."]
|
||||||
|
unique_name_in_owner = true
|
||||||
transform = Transform3D(0.707107, -0.5, 0.5, 0, 0.707107, 0.707107, -0.707107, -0.5, 0.5, 0, 5, 0)
|
transform = Transform3D(0.707107, -0.5, 0.5, 0, 0.707107, 0.707107, -0.707107, -0.5, 0.5, 0, 5, 0)
|
||||||
shadow_enabled = true
|
shadow_enabled = true
|
||||||
|
|
||||||
|
|||||||
@@ -71,6 +71,31 @@ var _ground_padding: float = 20.0
|
|||||||
get:
|
get:
|
||||||
return _ground_padding
|
return _ground_padding
|
||||||
|
|
||||||
|
var _day_length_hours: float = 12.0
|
||||||
|
@export_range(1.0, 48.0, 0.5) var day_length_hours: float = 12.0:
|
||||||
|
set(value):
|
||||||
|
value = max(value, 1.0)
|
||||||
|
if is_equal_approx(value, _day_length_hours):
|
||||||
|
return
|
||||||
|
_day_length_hours = value
|
||||||
|
_time_of_day_hours = clamp(_time_of_day_hours, 0.0, _day_length_hours)
|
||||||
|
_apply_sun_lighting()
|
||||||
|
get:
|
||||||
|
return _day_length_hours
|
||||||
|
|
||||||
|
var _seconds_per_game_hour: float = 60.0
|
||||||
|
@export_range(1.0, 600.0, 1.0) var real_seconds_per_game_hour: float = 60.0:
|
||||||
|
set(value):
|
||||||
|
value = clamp(value, 1.0, 600.0)
|
||||||
|
if is_equal_approx(value, _seconds_per_game_hour):
|
||||||
|
return
|
||||||
|
_seconds_per_game_hour = value
|
||||||
|
get:
|
||||||
|
return _seconds_per_game_hour
|
||||||
|
|
||||||
|
@export_range(0.0, 48.0, 0.25) var start_time_of_day_hours: float = 6.0
|
||||||
|
var _time_of_day_hours: float = 0.0
|
||||||
|
|
||||||
var _zoom_factor: float = 1.0
|
var _zoom_factor: float = 1.0
|
||||||
var _zoom_min_internal: float = 0.5
|
var _zoom_min_internal: float = 0.5
|
||||||
var _zoom_max_internal: float = 3.0
|
var _zoom_max_internal: float = 3.0
|
||||||
@@ -128,6 +153,7 @@ const _SQRT3 := 1.7320508075688772
|
|||||||
@onready var _grid_lines: MeshInstance3D = %GridLines
|
@onready var _grid_lines: MeshInstance3D = %GridLines
|
||||||
@onready var _camera: Camera3D = %Camera3D
|
@onready var _camera: Camera3D = %Camera3D
|
||||||
@onready var _hover_highlight: MeshInstance3D = %HoverHighlight
|
@onready var _hover_highlight: MeshInstance3D = %HoverHighlight
|
||||||
|
@onready var _sun_light: DirectionalLight3D = %DirectionalLight3D
|
||||||
|
|
||||||
var _grid_size: Vector2 = Vector2.ZERO
|
var _grid_size: Vector2 = Vector2.ZERO
|
||||||
var _cells: Dictionary = {}
|
var _cells: Dictionary = {}
|
||||||
@@ -138,6 +164,7 @@ var _hex_center_offset_local: Vector3 = Vector3.ZERO
|
|||||||
func _ready() -> void:
|
func _ready() -> void:
|
||||||
set_process(true)
|
set_process(true)
|
||||||
_zoom_factor = clamp(_zoom_factor, _zoom_min_internal, _zoom_max_internal)
|
_zoom_factor = clamp(_zoom_factor, _zoom_min_internal, _zoom_max_internal)
|
||||||
|
_time_of_day_hours = clamp(start_time_of_day_hours, 0.0, _day_length_hours)
|
||||||
_queue_rebuild()
|
_queue_rebuild()
|
||||||
|
|
||||||
func get_cells() -> Dictionary:
|
func get_cells() -> Dictionary:
|
||||||
@@ -181,6 +208,7 @@ func _rebuild_grid() -> void:
|
|||||||
_update_highlight_mesh()
|
_update_highlight_mesh()
|
||||||
_update_camera_view()
|
_update_camera_view()
|
||||||
_update_ground_assets()
|
_update_ground_assets()
|
||||||
|
_apply_sun_lighting()
|
||||||
emit_signal("grid_layout_changed", _cells)
|
emit_signal("grid_layout_changed", _cells)
|
||||||
|
|
||||||
func _update_ground_assets() -> void:
|
func _update_ground_assets() -> void:
|
||||||
@@ -428,11 +456,45 @@ func _compute_required_ground_size() -> Vector2:
|
|||||||
var padding_vec := Vector2.ONE * _ground_padding
|
var padding_vec := Vector2.ONE * _ground_padding
|
||||||
return (half_extents + padding_vec) * 2.0
|
return (half_extents + padding_vec) * 2.0
|
||||||
|
|
||||||
|
func _update_day_cycle(delta: float) -> void:
|
||||||
|
if _day_length_hours <= 0.0 or _seconds_per_game_hour <= 0.0:
|
||||||
|
return
|
||||||
|
_time_of_day_hours = fposmod(_time_of_day_hours + delta / _seconds_per_game_hour, _day_length_hours)
|
||||||
|
_apply_sun_lighting()
|
||||||
|
|
||||||
|
func _apply_sun_lighting() -> void:
|
||||||
|
if not is_instance_valid(_sun_light):
|
||||||
|
return
|
||||||
|
if _day_length_hours <= 0.0:
|
||||||
|
return
|
||||||
|
var cycle: float = 0.0
|
||||||
|
if _day_length_hours > 0.0:
|
||||||
|
cycle = fposmod(_time_of_day_hours / _day_length_hours, 1.0)
|
||||||
|
var sun_angle: float = cycle * TAU
|
||||||
|
var rotation_axis: Vector3 = Vector3(1.0, 0.0, -1.0).normalized()
|
||||||
|
if rotation_axis.length() == 0.0:
|
||||||
|
rotation_axis = Vector3.RIGHT
|
||||||
|
var direction: Vector3 = Vector3.UP.rotated(rotation_axis, sun_angle)
|
||||||
|
direction = direction.rotated(Vector3.UP, deg_to_rad(35.0)).normalized()
|
||||||
|
var target: Vector3 = global_transform.origin
|
||||||
|
var sun_distance: float = 60.0
|
||||||
|
var sun_position: Vector3 = target - direction * sun_distance
|
||||||
|
_sun_light.look_at_from_position(sun_position, target, Vector3.UP)
|
||||||
|
var daylight: float = clamp(direction.y * 0.5 + 0.5, 0.0, 1.0)
|
||||||
|
var dawn_color: Color = Color(0.95, 0.58, 0.32)
|
||||||
|
var night_color: Color = Color(0.12, 0.18, 0.35)
|
||||||
|
var day_color: Color = Color(1.0, 0.96, 0.88)
|
||||||
|
var warm_mix: Color = dawn_color.lerp(day_color, clamp((daylight - 0.25) / 0.5, 0.0, 1.0))
|
||||||
|
_sun_light.light_color = night_color.lerp(warm_mix, daylight)
|
||||||
|
_sun_light.light_energy = lerp(0.05, 1.25, daylight)
|
||||||
|
_sun_light.shadow_enabled = daylight > 0.1
|
||||||
|
|
||||||
func _process(_delta: float) -> void:
|
func _process(_delta: float) -> void:
|
||||||
if Engine.is_editor_hint():
|
if Engine.is_editor_hint():
|
||||||
return
|
return
|
||||||
var mouse_position: Vector2 = get_viewport().get_mouse_position()
|
var mouse_position: Vector2 = get_viewport().get_mouse_position()
|
||||||
_update_hovered_cell(mouse_position)
|
_update_hovered_cell(mouse_position)
|
||||||
|
_update_day_cycle(_delta)
|
||||||
|
|
||||||
func _unhandled_input(event: InputEvent) -> void:
|
func _unhandled_input(event: InputEvent) -> void:
|
||||||
if Engine.is_editor_hint():
|
if Engine.is_editor_hint():
|
||||||
@@ -445,7 +507,7 @@ func _unhandled_input(event: InputEvent) -> void:
|
|||||||
_adjust_zoom(_zoom_step_internal)
|
_adjust_zoom(_zoom_step_internal)
|
||||||
|
|
||||||
func _adjust_zoom(delta: float) -> void:
|
func _adjust_zoom(delta: float) -> void:
|
||||||
var previous := _zoom_factor
|
var previous: float = _zoom_factor
|
||||||
_zoom_factor = clamp(_zoom_factor + delta, _zoom_min_internal, _zoom_max_internal)
|
_zoom_factor = clamp(_zoom_factor + delta, _zoom_min_internal, _zoom_max_internal)
|
||||||
if is_equal_approx(previous, _zoom_factor):
|
if is_equal_approx(previous, _zoom_factor):
|
||||||
return
|
return
|
||||||
|
|||||||
Reference in New Issue
Block a user