diff --git a/client/scripts/player.gd b/client/scripts/player.gd index dae6c64..9c519e2 100644 --- a/client/scripts/player.gd +++ b/client/scripts/player.gd @@ -73,11 +73,24 @@ func _floor_y_under_body() -> float: return maxf(y_center, y_lower) +## Footing under goal xz (surface Y). Server goal.y may be capsule center (e.g. 0.9) or pick surface +## (e.g. 0) — do not compare that directly to `_floor_y_under_body()` (always surface). +func _destination_footing_y() -> float: + var g: Vector3 = _auth_walk_goal + var probe_top: float = maxf(global_position.y, g.y) + 4.0 + var probe: Vector3 = Vector3(g.x, probe_top, g.z) + var y: float = _ray_floor_y_at(probe) + if y >= probe_top - 0.05: + return g.y + return y + + func _nav_short_step_down_use_goal_direct() -> bool: var floor_y: float = _floor_y_under_body() - if _auth_walk_goal.y >= floor_y - STEP_OFF_FLOOR_MARGIN: + var dest_floor_y: float = _destination_footing_y() + if dest_floor_y >= floor_y - STEP_OFF_FLOOR_MARGIN: return false - var drop: float = floor_y - _auth_walk_goal.y + var drop: float = floor_y - dest_floor_y if drop < STEP_OFF_MIN_DROP or drop > STEP_OFF_MAX_DROP: return false var hd: float = Vector2( @@ -105,8 +118,11 @@ func _physics_process(_delta: float) -> void: var full_to_goal: Vector3 = _auth_walk_goal - global_position var horiz_dist: float = Vector2(full_to_goal.x, full_to_goal.z).length() - var vert_err: float = absf(full_to_goal.y) - if horiz_dist <= ARRIVE_EPS and vert_err <= VERT_ARRIVE_EPS: + var vert_err_capsule: float = absf(full_to_goal.y) + var footing_match: bool = ( + absf(_floor_y_under_body() - _destination_footing_y()) <= VERT_ARRIVE_EPS + ) + if horiz_dist <= ARRIVE_EPS and (vert_err_capsule <= VERT_ARRIVE_EPS or footing_match): velocity = Vector3.ZERO _has_walk_goal = false _nav_agent.set_target_position(global_position)