NEON-29: Reliable descend lip peel + capped floor snap
Wall/slide heuristics missed many step→floor stalls (e.g. far floor clicks). While descending with is_on_floor, always add gravity to vy before move_and_slide. Cap floor_snap_length when feet stay meaningfully above the goal so strong snap cannot yank the capsule back onto the step internal edge; cap lifts near landing (feet within 8 cm of goal Y). Apply snap helper on nomap + descend branches.pull/41/head
parent
f70dbe8f88
commit
cc63e9bdd7
|
|
@ -28,6 +28,9 @@ const IDLE_MANUAL_CORRECTION_MAX_TICKS: int = 8
|
|||
## Horizontal nudge per tick for rim / straddle settle (**`_maybe_idle_rim_settle_nudge`**).
|
||||
const IDLE_RIM_SETTLE_STEP: float = 0.004
|
||||
const DESCEND_GOAL_Y_MARGIN: float = 0.06
|
||||
## Cap floor snap while descending from a step so Jolt cannot snap the capsule back onto the
|
||||
## upper surface across an internal edge (lip hang). Relaxed once feet are near the goal height.
|
||||
const DESCEND_LIP_SNAP_CAP: float = 0.12
|
||||
## Y lift when blocked by wall-ish slide but nav goal is higher (stepped bumps).
|
||||
const WALK_STEP_ASSIST_DELTA: float = 0.11
|
||||
## Skip assist when horizontal velocity already aligns enough with want-dir (corners slide slowly).
|
||||
|
|
@ -254,24 +257,28 @@ func _apply_walk_air_gravity(delta: float) -> void:
|
|||
if not is_on_floor():
|
||||
velocity += g_step
|
||||
return
|
||||
# Descending toward a lower surface (e.g. first terrace step → main floor): rim / internal
|
||||
# edge contact can keep `is_on_floor()` true on the upper surface while the step's vertical
|
||||
# face zeros horizontal motion. With vy forced to 0 by `_set_horizontal_velocity_toward`,
|
||||
# no gravity ran and the capsule could hang until a new click retargeted. Shallow 0.3 m
|
||||
# drops hit this more often than taller platform→floor descents.
|
||||
var feet_on_floor: float = capsule_feet_y(global_position.y, CAPSULE_HALF_HEIGHT + PLAYER_CAPSULE_RADIUS)
|
||||
# Descending toward a lower surface: `is_on_floor()` can stay true on the upper step while
|
||||
# horizontal motion is blocked (internal edge / lip). `is_on_wall()` is unreliable here, and
|
||||
# a far floor click keeps large horiz delta so wall heuristics never ran. Always integrate
|
||||
# downward acceleration while on the upper surface; `move_and_slide` + floor collision
|
||||
# absorbs it on flat spans, and it peels the capsule off the lip when forward motion stalls.
|
||||
var feet_y: float = capsule_feet_y(global_position.y, CAPSULE_HALF_HEIGHT + PLAYER_CAPSULE_RADIUS)
|
||||
var descending: bool = (
|
||||
_has_walk_goal and _auth_walk_goal.y < feet_on_floor - DESCEND_GOAL_Y_MARGIN
|
||||
_has_walk_goal and _auth_walk_goal.y < feet_y - DESCEND_GOAL_Y_MARGIN
|
||||
)
|
||||
if descending and g_step.y < 0.0:
|
||||
var wallish: bool = is_on_wall()
|
||||
if not wallish:
|
||||
for i: int in get_slide_collision_count():
|
||||
if get_slide_collision(i).get_normal().y < 0.55:
|
||||
wallish = true
|
||||
break
|
||||
if wallish:
|
||||
velocity.y += g_step.y
|
||||
velocity.y += g_step.y
|
||||
|
||||
|
||||
func _walk_floor_snap_length(feet_y: float) -> float:
|
||||
var fl: float = WALK_STEP_ASSIST_SNAP if _step_assist_active else FLOOR_SNAP_MOVING
|
||||
if (
|
||||
_has_walk_goal
|
||||
and _auth_walk_goal.y < feet_y - DESCEND_GOAL_Y_MARGIN
|
||||
and feet_y > _auth_walk_goal.y + 0.08
|
||||
):
|
||||
fl = minf(fl, DESCEND_LIP_SNAP_CAP)
|
||||
return fl
|
||||
|
||||
|
||||
## When the authoritative goal shares XZ with the capsule (e.g. terrace above), horizontal
|
||||
|
|
@ -626,7 +633,9 @@ func _physics_process(delta: float) -> void:
|
|||
if NavigationServer3D.map_get_iteration_id(nav_map) == 0:
|
||||
_set_horizontal_velocity_toward(_auth_walk_goal, want_goal_h)
|
||||
_apply_walk_air_gravity(delta)
|
||||
floor_snap_length = WALK_STEP_ASSIST_SNAP if _step_assist_active else FLOOR_SNAP_MOVING
|
||||
floor_snap_length = _walk_floor_snap_length(
|
||||
capsule_feet_y(global_position.y, CAPSULE_HALF_HEIGHT + PLAYER_CAPSULE_RADIUS)
|
||||
)
|
||||
move_and_slide()
|
||||
_after_walk_move_and_slide()
|
||||
if _step_assist_active and (
|
||||
|
|
@ -647,7 +656,7 @@ func _physics_process(delta: float) -> void:
|
|||
if _auth_walk_goal.y < feet_y - DESCEND_GOAL_Y_MARGIN:
|
||||
_set_horizontal_velocity_toward(_auth_walk_goal, want_goal_h)
|
||||
_apply_walk_air_gravity(delta)
|
||||
floor_snap_length = WALK_STEP_ASSIST_SNAP if _step_assist_active else FLOOR_SNAP_MOVING
|
||||
floor_snap_length = _walk_floor_snap_length(feet_y)
|
||||
move_and_slide()
|
||||
_after_walk_move_and_slide()
|
||||
if _step_assist_active and (
|
||||
|
|
|
|||
Loading…
Reference in New Issue