NEON-29: Fix walk ledge probes for descending + same-column clicks
Degenerate XZ (velocity and want_goal_h ~0) made _walk_has_close_floor_probe_below return after center-only, suppressing ledge gravity for the whole move. Add _resolve_walk_probe_dir_xz: when goal surface is below feet, prefer horizontal bearing to the goal, else nav path lookahead, else fallbacks. Non-descending motion keeps velocity-first probes. Remove the nav-column-only want_goal_h override (superseded by descending branch). Reverts the regression where the capsule stayed on violet until XZ.pull/41/head
parent
db1f4da068
commit
91b802c679
|
|
@ -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)
|
||||
|
|
|
|||
Loading…
Reference in New Issue