fix terrain collision and water recovery
This commit is contained in:
parent
da7f072365
commit
1ab2a291d2
13 changed files with 110 additions and 11 deletions
|
|
@ -29,9 +29,14 @@ enum EntryHeightReference {
|
|||
)
|
||||
## Recovery begins when the selected reference reaches this depth.
|
||||
@export_range(0.0, 2.0, 0.05) var entry_depth_threshold: float = 0.35
|
||||
## The player must remain below the threshold for this long before recovery.
|
||||
## A short freshwater confirmation keeps jumps across stepping stones from
|
||||
## being mistaken for a completed fall into the water.
|
||||
@export_range(0.0, 1.0, 0.05) var entry_confirmation_seconds: float = 0.0
|
||||
|
||||
var _tracked_players: Array[Player] = []
|
||||
var _triggered_players: Dictionary[StringName, bool] = {}
|
||||
var _submerged_seconds: Dictionary[StringName, float] = {}
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
|
|
@ -46,7 +51,7 @@ func _ready() -> void:
|
|||
set_physics_process(false)
|
||||
|
||||
|
||||
func _physics_process(_delta: float) -> void:
|
||||
func _physics_process(delta: float) -> void:
|
||||
var active_surface_height: float = get_surface_height()
|
||||
for player: Player in _tracked_players.duplicate():
|
||||
if not is_instance_valid(player):
|
||||
|
|
@ -58,9 +63,17 @@ func _physics_process(_delta: float) -> void:
|
|||
var entry_height := player.get_body_center_position().y
|
||||
if entry_height_reference == EntryHeightReference.PLAYER_ORIGIN:
|
||||
entry_height = player.global_position.y
|
||||
if entry_height <= active_surface_height - entry_depth_threshold:
|
||||
_triggered_players[player_key] = true
|
||||
recovery_requested.emit(player, active_surface_height)
|
||||
if entry_height > active_surface_height - entry_depth_threshold:
|
||||
_submerged_seconds[player_key] = 0.0
|
||||
continue
|
||||
var submerged_seconds: float = (
|
||||
_submerged_seconds.get(player_key, 0.0) + maxf(delta, 0.0)
|
||||
)
|
||||
_submerged_seconds[player_key] = submerged_seconds
|
||||
if submerged_seconds < entry_confirmation_seconds:
|
||||
continue
|
||||
_triggered_players[player_key] = true
|
||||
recovery_requested.emit(player, active_surface_height)
|
||||
if _tracked_players.is_empty():
|
||||
set_physics_process(false)
|
||||
|
||||
|
|
@ -86,6 +99,7 @@ func _on_body_entered(body: Node3D) -> void:
|
|||
if player == null or player in _tracked_players:
|
||||
return
|
||||
_tracked_players.append(player)
|
||||
_submerged_seconds[StringName(str(player.get_instance_id()))] = 0.0
|
||||
set_physics_process(true)
|
||||
|
||||
|
||||
|
|
@ -94,6 +108,8 @@ func _on_body_exited(body: Node3D) -> void:
|
|||
if player == null:
|
||||
return
|
||||
_tracked_players.erase(player)
|
||||
_triggered_players.erase(StringName(str(player.get_instance_id())))
|
||||
var player_key := StringName(str(player.get_instance_id()))
|
||||
_triggered_players.erase(player_key)
|
||||
_submerged_seconds.erase(player_key)
|
||||
if _tracked_players.is_empty():
|
||||
set_physics_process(false)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue