Giving character sleep requirements, when character gets tired it goes home and sleeps
This commit is contained in:
@@ -8,6 +8,8 @@ class_name GridCharacterController
|
|||||||
@export_range(0.1, 20.0, 0.1) var move_speed: float = 4.0
|
@export_range(0.1, 20.0, 0.1) var move_speed: float = 4.0
|
||||||
@export_range(0.0, 2.0, 0.01) var height_offset: float = 0.3
|
@export_range(0.0, 2.0, 0.01) var height_offset: float = 0.3
|
||||||
@export var home_marker_scene: PackedScene
|
@export var home_marker_scene: PackedScene
|
||||||
|
@export_range(1.0, 16.0, 0.5) var sleep_requirement_hours: float = 8.0
|
||||||
|
@export var day_night_controller_path: NodePath
|
||||||
|
|
||||||
var _grid_manager: GridPlaneManager = null
|
var _grid_manager: GridPlaneManager = null
|
||||||
var _camera: Camera3D = null
|
var _camera: Camera3D = null
|
||||||
@@ -15,6 +17,13 @@ var _current_cell: Vector2i = Vector2i(-1, -1)
|
|||||||
var _target_position: Vector3
|
var _target_position: Vector3
|
||||||
var _is_moving: bool = false
|
var _is_moving: bool = false
|
||||||
var _home_instance: Node3D = null
|
var _home_instance: Node3D = null
|
||||||
|
var _day_night_controller: DayNightController = null
|
||||||
|
var _last_time_hours: float = 0.0
|
||||||
|
var _awake_accum_hours: float = 0.0
|
||||||
|
var _sleep_accum_hours: float = 0.0
|
||||||
|
var _is_sleeping: bool = false
|
||||||
|
var _sleep_pending_return: bool = false
|
||||||
|
var _awake_duration_hours: float = 0.0
|
||||||
|
|
||||||
func _ready() -> void:
|
func _ready() -> void:
|
||||||
set_physics_process(true)
|
set_physics_process(true)
|
||||||
@@ -24,6 +33,13 @@ func _ready() -> void:
|
|||||||
_grid_manager.grid_layout_changed.connect(_on_grid_layout_changed)
|
_grid_manager.grid_layout_changed.connect(_on_grid_layout_changed)
|
||||||
_move_to_cell(start_cell, true)
|
_move_to_cell(start_cell, true)
|
||||||
_spawn_home()
|
_spawn_home()
|
||||||
|
_update_awake_duration()
|
||||||
|
if _day_night_controller:
|
||||||
|
_last_time_hours = _day_night_controller.get_time_of_day_hours()
|
||||||
|
else:
|
||||||
|
_last_time_hours = 0.0
|
||||||
|
_is_sleeping = false
|
||||||
|
_sleep_pending_return = false
|
||||||
|
|
||||||
func _physics_process(delta: float) -> void:
|
func _physics_process(delta: float) -> void:
|
||||||
if not _is_moving:
|
if not _is_moving:
|
||||||
@@ -33,6 +49,8 @@ func _physics_process(delta: float) -> void:
|
|||||||
if distance <= 0.01:
|
if distance <= 0.01:
|
||||||
global_position = _target_position
|
global_position = _target_position
|
||||||
_is_moving = false
|
_is_moving = false
|
||||||
|
if _sleep_pending_return and _current_cell == start_cell:
|
||||||
|
_enter_sleep_state()
|
||||||
return
|
return
|
||||||
var step: float = move_speed * delta
|
var step: float = move_speed * delta
|
||||||
var move_vector: Vector3 = direction.normalized() * min(step, distance)
|
var move_vector: Vector3 = direction.normalized() * min(step, distance)
|
||||||
@@ -41,12 +59,16 @@ func _physics_process(delta: float) -> void:
|
|||||||
func _unhandled_input(event: InputEvent) -> void:
|
func _unhandled_input(event: InputEvent) -> void:
|
||||||
if Engine.is_editor_hint():
|
if Engine.is_editor_hint():
|
||||||
return
|
return
|
||||||
|
if _is_sleeping or _sleep_pending_return:
|
||||||
|
return
|
||||||
if event is InputEventMouseButton and event.pressed and event.button_index == MOUSE_BUTTON_LEFT:
|
if event is InputEventMouseButton and event.pressed and event.button_index == MOUSE_BUTTON_LEFT:
|
||||||
_move_to_mouse_click()
|
_move_to_mouse_click()
|
||||||
|
|
||||||
func _move_to_mouse_click() -> void:
|
func _move_to_mouse_click() -> void:
|
||||||
if not _grid_manager or not _camera:
|
if not _grid_manager or not _camera:
|
||||||
return
|
return
|
||||||
|
if _is_sleeping or _sleep_pending_return:
|
||||||
|
return
|
||||||
var viewport: Viewport = get_viewport()
|
var viewport: Viewport = get_viewport()
|
||||||
if viewport == null:
|
if viewport == null:
|
||||||
return
|
return
|
||||||
@@ -66,6 +88,8 @@ func _move_to_cell(cell: Vector2i, instant: bool = false) -> void:
|
|||||||
if instant:
|
if instant:
|
||||||
global_position = _target_position
|
global_position = _target_position
|
||||||
_is_moving = false
|
_is_moving = false
|
||||||
|
if _sleep_pending_return and cell == start_cell:
|
||||||
|
_enter_sleep_state()
|
||||||
else:
|
else:
|
||||||
_is_moving = true
|
_is_moving = true
|
||||||
|
|
||||||
@@ -103,6 +127,11 @@ func _resolve_references() -> void:
|
|||||||
_camera = get_node_or_null(camera_path) as Camera3D
|
_camera = get_node_or_null(camera_path) as Camera3D
|
||||||
if not _home_instance and home_marker_scene:
|
if not _home_instance and home_marker_scene:
|
||||||
_spawn_home()
|
_spawn_home()
|
||||||
|
if day_night_controller_path != NodePath():
|
||||||
|
_day_night_controller = get_node_or_null(day_night_controller_path) as DayNightController
|
||||||
|
else:
|
||||||
|
_day_night_controller = get_node_or_null("../DirectionalLight3D") as DayNightController
|
||||||
|
_connect_day_night()
|
||||||
|
|
||||||
func _spawn_home() -> void:
|
func _spawn_home() -> void:
|
||||||
if not home_marker_scene or not _grid_manager:
|
if not home_marker_scene or not _grid_manager:
|
||||||
@@ -135,3 +164,55 @@ func _update_home_position() -> void:
|
|||||||
var local_center := _grid_manager.cell_to_world(start_cell)
|
var local_center := _grid_manager.cell_to_world(start_cell)
|
||||||
var world_center := _grid_manager.to_global(local_center)
|
var world_center := _grid_manager.to_global(local_center)
|
||||||
_home_instance.global_position = world_center + Vector3.UP * 0.01
|
_home_instance.global_position = world_center + Vector3.UP * 0.01
|
||||||
|
|
||||||
|
func _connect_day_night() -> void:
|
||||||
|
if _day_night_controller and not _day_night_controller.is_connected("time_changed", Callable(self, "_on_time_changed")):
|
||||||
|
_day_night_controller.time_changed.connect(_on_time_changed)
|
||||||
|
_update_awake_duration()
|
||||||
|
|
||||||
|
func _update_awake_duration() -> void:
|
||||||
|
var total_hours := sleep_requirement_hours + 1.0
|
||||||
|
if _day_night_controller:
|
||||||
|
total_hours = _day_night_controller.get_day_length_hours()
|
||||||
|
_awake_duration_hours = max(total_hours - sleep_requirement_hours, 0.1)
|
||||||
|
|
||||||
|
func _on_time_changed(current_hours: float) -> void:
|
||||||
|
if _day_night_controller == null:
|
||||||
|
return
|
||||||
|
var delta := _compute_time_delta(current_hours)
|
||||||
|
_last_time_hours = current_hours
|
||||||
|
if _is_sleeping:
|
||||||
|
_sleep_accum_hours += delta
|
||||||
|
if _sleep_accum_hours >= sleep_requirement_hours:
|
||||||
|
_exit_sleep_state()
|
||||||
|
else:
|
||||||
|
if _sleep_pending_return:
|
||||||
|
return
|
||||||
|
_awake_accum_hours += delta
|
||||||
|
if _awake_accum_hours >= _awake_duration_hours:
|
||||||
|
_begin_sleep_cycle()
|
||||||
|
|
||||||
|
func _compute_time_delta(current_hours: float) -> float:
|
||||||
|
var day_length := _day_night_controller.get_day_length_hours() if _day_night_controller else 24.0
|
||||||
|
var delta := current_hours - _last_time_hours
|
||||||
|
if delta < 0.0:
|
||||||
|
delta += day_length
|
||||||
|
return delta
|
||||||
|
|
||||||
|
func _begin_sleep_cycle() -> void:
|
||||||
|
if _sleep_pending_return or _is_sleeping:
|
||||||
|
return
|
||||||
|
_sleep_pending_return = true
|
||||||
|
_sleep_accum_hours = 0.0
|
||||||
|
_move_to_cell(start_cell)
|
||||||
|
|
||||||
|
func _enter_sleep_state() -> void:
|
||||||
|
_sleep_pending_return = false
|
||||||
|
_is_sleeping = true
|
||||||
|
_sleep_accum_hours = 0.0
|
||||||
|
|
||||||
|
func _exit_sleep_state() -> void:
|
||||||
|
_is_sleeping = false
|
||||||
|
_sleep_pending_return = false
|
||||||
|
_sleep_accum_hours = 0.0
|
||||||
|
_awake_accum_hours = 0.0
|
||||||
|
|||||||
@@ -113,8 +113,10 @@ transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -4.5, 0.3, -4.5)
|
|||||||
script = ExtResource("5_n4d0h")
|
script = ExtResource("5_n4d0h")
|
||||||
grid_manager_path = NodePath("..")
|
grid_manager_path = NodePath("..")
|
||||||
camera_path = NodePath("../Camera3D")
|
camera_path = NodePath("../Camera3D")
|
||||||
|
start_cell = Vector2i(0, 0)
|
||||||
move_speed = 5.0
|
move_speed = 5.0
|
||||||
home_marker_scene = ExtResource("7_1vmu7")
|
home_marker_scene = ExtResource("7_1vmu7")
|
||||||
|
day_night_controller_path = NodePath("../DirectionalLight3D")
|
||||||
|
|
||||||
[node name="Mesh" type="MeshInstance3D" parent="GridCharacter"]
|
[node name="Mesh" type="MeshInstance3D" parent="GridCharacter"]
|
||||||
material_override = SubResource("StandardMaterial3D_character")
|
material_override = SubResource("StandardMaterial3D_character")
|
||||||
|
|||||||
Reference in New Issue
Block a user