diff --git a/client/scripts/player.gd b/client/scripts/player.gd index adac43c..eae90e2 100644 --- a/client/scripts/player.gd +++ b/client/scripts/player.gd @@ -373,6 +373,39 @@ func _walk_ray_hit_up_floor(space: PhysicsDirectSpaceState3D, off_xz: Vector2) - return n.dot(Vector3.UP) > WALK_SUPPORT_PROBE_MIN_UP_DOT +## Horizontal bearing for walk ledge / continuation rays. Must not stay ~zero while descending: a +## floor click **under** the capsule ([code]want_goal_h ≈ 0[/code]) used to leave [code]walk_move_dir_xz[/code] +## empty so [method _walk_has_close_floor_probe_below] took the center-only fast path and never +## applied ledge gravity until XZ arrival. +func _resolve_walk_probe_dir_xz(feet_y: float, want_goal_h: Vector3) -> Vector2: + var pos := global_position + var to_g := Vector2(_auth_walk_goal.x - pos.x, _auth_walk_goal.z - pos.z) + var vxz := Vector2(velocity.x, velocity.z) + var wh := Vector2(want_goal_h.x, want_goal_h.z) + var descending: bool = ( + _has_walk_goal and _auth_walk_goal.y < feet_y - DESCEND_GOAL_Y_MARGIN + ) + if descending: + if to_g.length_squared() >= 1e-6: + return to_g + if wh.length_squared() >= 1e-8: + return wh + var path: PackedVector3Array = _nav_agent.get_current_navigation_path() + var min_l2: float = NAV_PATH_STEER_MIN_LOOKAHEAD * NAV_PATH_STEER_MIN_LOOKAHEAD + for i: int in range(path.size()): + var d := Vector2(path[i].x - pos.x, path[i].z - pos.z) + if d.length_squared() >= min_l2: + return d + if to_g.length_squared() > 1e-12: + return to_g + if vxz.length_squared() >= 1e-8: + return vxz + return Vector2(1.0, 0.0) + if vxz.length_squared() < 1e-10: + return wh + return vxz + + ## Walkable support for **continued** forward motion within [member WALK_SUPPORT_PROBE_DEPTH]. ## Requires a hit under the foot origin **and** at least one sample **ahead** in [param move_dir_xz] ## (same construction as [method _walk_probe_xz_offsets]). If only the center hits while the leading @@ -944,23 +977,7 @@ func _physics_process(delta: float) -> void: else: _set_horizontal_velocity_toward(_auth_walk_goal, want_goal_h) - # Prefer [param velocity] XZ so probes match [code]move_and_slide[/code] / path steering (NEON-16). - # Exception: with **column** path steering toward a **lower** click, velocity often hugs the baked - # path tangent on TerracePlatformB (violet) while [param want_goal_h] points at the floor — rays - # along velocity keep hitting deck ahead → false “support” and no ledge gravity until XZ closes - # (violet → gold → floor). Use click bearing for probes in that case only. - var walk_move_dir_xz := Vector2(velocity.x, velocity.z) - if walk_move_dir_xz.length_squared() < 1e-10: - walk_move_dir_xz = Vector2(want_goal_h.x, want_goal_h.z) - elif ( - needs_vertical_routing - and _walk_nav_column_steering - and is_on_floor() - and _auth_walk_goal.y < feet_y - DESCEND_GOAL_Y_MARGIN - ): - var wh2 := Vector2(want_goal_h.x, want_goal_h.z) - if wh2.length_squared() > 1e-10: - walk_move_dir_xz = wh2 + var walk_move_dir_xz: Vector2 = _resolve_walk_probe_dir_xz(feet_y, want_goal_h) _apply_walk_air_gravity(delta, walk_move_dir_xz) floor_snap_length = _walk_floor_snap_length(feet_y, want_goal_h, walk_move_dir_xz)