NEON-29: Extend tread peel suspend when vlat unlatches.
Widen vertical-route latch off-sep (0.038→0.085) so descent toward floor does not drop vlat while feet still wobble on stairs. Add horiz+vert fallback: suspend peel and restore snap when vert_sep ≤0.34 m and horiz_dist ≤2 m, covering ncol=false paths where goal Y matches slab height but tread peel still fought snap (violet stairs ~y=0.92).pull/41/head
parent
26ad33230d
commit
4e47e9a037
|
|
@ -32,11 +32,19 @@ const NAV_PATH_STEER_MIN_GOAL_DOT: float = -0.25
|
|||
## (3-cycle NEON-16 traces: same XZ triplet, Y/feet_y ping-pong). Suspend peel and allow normal snap when the
|
||||
## feet are within this vertical distance of the goal **surface** (m).
|
||||
const WALK_PEEL_SUSPEND_VERT_SEP: float = 0.48
|
||||
## Fallback when [code]vlat[/code] has unlatched (feet and goal both near the same slab Y) but
|
||||
## [code]ncol[/code] is false because [code]horiz_dist[/code] is past column hysteresis — peel + zero
|
||||
## snap still oscillates on violet treads (NEON-16 ~y=0.92). Tighter than [member WALK_PEEL_SUSPEND_VERT_SEP]
|
||||
## so terrace lips with ~0.45–0.55 m drop keep peel until XZ is tighter.
|
||||
const WALK_PEEL_SUSPEND_HORIZ_VERT_SEP: float = 0.34
|
||||
const WALK_PEEL_SUSPEND_HORIZ_DIST: float = 2.0
|
||||
## Hysteresis for [code]needs_vertical_routing[/code]: [code]feet_y[/code] wobbles with
|
||||
## [code]move_and_slide[/code] on treads (~7 cm), so a single margin (see [member DESCEND_GOAL_Y_MARGIN])
|
||||
## can flip path vs direct steering every tick → velocity sign ping-pong while [code]has_goal[/code].
|
||||
const WALK_VERT_ROUTE_LATCH_ON_SEP: float = 0.10
|
||||
const WALK_VERT_ROUTE_LATCH_OFF_SEP: float = 0.038
|
||||
## Stay below [member WALK_VERT_ROUTE_LATCH_ON_SEP]. Old 0.038 unlatched while descending toward floor
|
||||
## (vert_sep under ~4 cm) → [code]vlat[/code]/[code]ncol[/code] false → peel suspend never ran.
|
||||
const WALK_VERT_ROUTE_LATCH_OFF_SEP: float = 0.085
|
||||
const FLOOR_SNAP_MOVING: float = 0.32
|
||||
## Idle floor snap length (stronger to pin rim contacts).
|
||||
const FLOOR_SNAP_IDLE: float = 0.11
|
||||
|
|
@ -466,19 +474,18 @@ func _apply_walk_air_gravity(delta: float, _feet_y: float, _move_dir_xz: Vector2
|
|||
velocity += _player_vertical_accel(delta) * delta
|
||||
|
||||
|
||||
func _walk_peel_suspend_on_column_treads(feet_y: float) -> bool:
|
||||
return (
|
||||
_walk_vert_route_latched
|
||||
and _walk_nav_column_steering
|
||||
and absf(_auth_walk_goal.y - feet_y) < WALK_PEEL_SUSPEND_VERT_SEP
|
||||
)
|
||||
func _walk_peel_suspend_near_goal(feet_y: float, horiz_dist: float) -> bool:
|
||||
var vsep: float = absf(_auth_walk_goal.y - feet_y)
|
||||
if _walk_vert_route_latched and _walk_nav_column_steering and vsep < WALK_PEEL_SUSPEND_VERT_SEP:
|
||||
return true
|
||||
return vsep <= WALK_PEEL_SUSPEND_HORIZ_VERT_SEP and horiz_dist <= WALK_PEEL_SUSPEND_HORIZ_DIST
|
||||
|
||||
|
||||
## After [method move_and_slide], peel the capsule down when the authoritative goal is below the feet
|
||||
## but the engine still reports floor contact (GROUNDED mode ate negative [code]velocity.y[/code]).
|
||||
## Uses a small accumulated peel speed so displacement matches [code]∫ g dt[/code], not [code]g Δt[/code] (wrong units).
|
||||
func _apply_walk_post_slide_ledge_peel(
|
||||
delta: float, feet_y: float, move_dir_xz: Vector2
|
||||
delta: float, feet_y: float, move_dir_xz: Vector2, horiz_dist: float
|
||||
) -> void:
|
||||
if not _has_walk_goal:
|
||||
_walk_ledge_peel_vy = 0.0
|
||||
|
|
@ -495,7 +502,7 @@ func _apply_walk_post_slide_ledge_peel(
|
|||
if _auth_walk_goal.y > feet_y + 0.04:
|
||||
_walk_ledge_peel_vy = 0.0
|
||||
return
|
||||
if _walk_peel_suspend_on_column_treads(feet_y):
|
||||
if _walk_peel_suspend_near_goal(feet_y, horiz_dist):
|
||||
_walk_ledge_peel_vy = 0.0
|
||||
return
|
||||
var peel: bool = (
|
||||
|
|
@ -513,7 +520,10 @@ func _apply_walk_post_slide_ledge_peel(
|
|||
|
||||
|
||||
func _walk_floor_snap_length(
|
||||
feet_y: float, want_goal_h: Vector3, move_dir_xz: Vector2 = Vector2.ZERO
|
||||
feet_y: float,
|
||||
want_goal_h: Vector3,
|
||||
move_dir_xz: Vector2 = Vector2.ZERO,
|
||||
horiz_dist: float = INF,
|
||||
) -> float:
|
||||
if _step_assist_active:
|
||||
return WALK_STEP_ASSIST_SNAP
|
||||
|
|
@ -521,7 +531,7 @@ func _walk_floor_snap_length(
|
|||
# Strong moving snap + lip [code]is_on_floor()[/code] otherwise cancels gravity every tick.
|
||||
if (
|
||||
is_on_floor()
|
||||
and not _walk_peel_suspend_on_column_treads(feet_y)
|
||||
and not _walk_peel_suspend_near_goal(feet_y, horiz_dist)
|
||||
and (
|
||||
not _walk_has_close_floor_probe_below(move_dir_xz)
|
||||
or feet_y > _auth_walk_goal.y + WALK_DEEP_DESCENT_FEET_ABOVE_GOAL
|
||||
|
|
@ -1059,12 +1069,14 @@ func _physics_process(delta: float) -> void:
|
|||
var walk_move_dir_xz: Vector2 = _resolve_walk_probe_dir_xz(feet_y, want_goal_h)
|
||||
|
||||
_apply_walk_air_gravity(delta, feet_y, walk_move_dir_xz)
|
||||
floor_snap_length = _walk_floor_snap_length(feet_y, want_goal_h, walk_move_dir_xz)
|
||||
floor_snap_length = _walk_floor_snap_length(
|
||||
feet_y, want_goal_h, walk_move_dir_xz, horiz_dist
|
||||
)
|
||||
move_and_slide()
|
||||
var feet_after: float = capsule_feet_y(
|
||||
global_position.y, CAPSULE_HALF_HEIGHT + PLAYER_CAPSULE_RADIUS
|
||||
)
|
||||
_apply_walk_post_slide_ledge_peel(delta, feet_after, walk_move_dir_xz)
|
||||
_apply_walk_post_slide_ledge_peel(delta, feet_after, walk_move_dir_xz, horiz_dist)
|
||||
_after_walk_move_and_slide()
|
||||
_clear_step_assist_after_walk_move()
|
||||
_debug_trace_transform("physics")
|
||||
|
|
|
|||
Loading…
Reference in New Issue