NEON-29: Reject 180° walk steering flips on stair edges.
Path lookahead vs direct goal could reverse horizontal velocity every physics tick on treads (NEON-16), driving slide/snap Y jitter. Clamp new steer to prior bearing when dot < -0.35 and speed is above a small threshold. Widen NAV_COLUMN_STEER_EXIT_DIST (0.97→1.12) to reduce path/direct mode chatter when horiz_dist wobbles near the old band.pull/41/head
parent
038505ea3e
commit
bfc70678c4
|
|
@ -21,13 +21,18 @@ const DIRECT_APPROACH_RADIUS: float = 0.85
|
|||
## tangentially → [code]horiz_dist[/code] crosses the radius → direct vs path
|
||||
## alternates → velocity sign flips (Jolt ping-pong while [code]has_goal[/code]).
|
||||
const NAV_COLUMN_STEER_ENTER_DIST: float = 0.74
|
||||
const NAV_COLUMN_STEER_EXIT_DIST: float = 0.97
|
||||
const NAV_COLUMN_STEER_EXIT_DIST: float = 1.12
|
||||
## First path waypoint used for column steer must be at least this far in XZ. [method NavigationAgent3D.get_next_path_position]
|
||||
## can sit ~4 cm from the capsule; Jolt slides ~4 cm/tick → the “toward next” vector flips 180° every frame
|
||||
## (`vlat && ncol` NEON-16 traces). A 22 cm gate matches foot-scale probes and stays stable on treads.
|
||||
const NAV_PATH_STEER_MIN_LOOKAHEAD: float = 0.22
|
||||
## If lookahead steering points more than ~105° from the click direction (XZ), use direct goal steer instead.
|
||||
const NAV_PATH_STEER_MIN_GOAL_DOT: float = -0.25
|
||||
## On tread edges, path vs direct or waypoint lookahead can flip the horizontal seek vector ~180° each
|
||||
## physics tick → [method move_and_slide] + snap Y noise (~7 cm, NEON-16). Keep prior bearing if the new
|
||||
## direction is more than ~110° from current horizontal [member velocity].
|
||||
const WALK_STEER_REVERSE_REJECT_DOT: float = -0.35
|
||||
const WALK_STEER_MIN_CUR_SPEED_SQ: float = 0.16
|
||||
## While [code]vlat && ncol[/code], ledge peel + zero floor snap fight [method move_and_slide] on approach treads
|
||||
## (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).
|
||||
|
|
@ -358,6 +363,20 @@ func _clear_step_assist_after_walk_move() -> void:
|
|||
_step_assist_active = false
|
||||
|
||||
|
||||
func _walk_clamp_steering_reverse(desired_dir_xz: Vector3) -> Vector3:
|
||||
var d2 := Vector2(desired_dir_xz.x, desired_dir_xz.z)
|
||||
if d2.length_squared() < 1e-10:
|
||||
return desired_dir_xz
|
||||
d2 = d2.normalized()
|
||||
var cur := Vector2(velocity.x, velocity.z)
|
||||
if cur.length_squared() < WALK_STEER_MIN_CUR_SPEED_SQ:
|
||||
return Vector3(d2.x, 0.0, d2.y)
|
||||
var cur_n := cur.normalized()
|
||||
if d2.dot(cur_n) < WALK_STEER_REVERSE_REJECT_DOT:
|
||||
return Vector3(cur_n.x, 0.0, cur_n.y)
|
||||
return Vector3(d2.x, 0.0, d2.y)
|
||||
|
||||
|
||||
func _set_horizontal_velocity_toward(
|
||||
point: Vector3, fallback_dir_xz: Vector3 = Vector3.ZERO
|
||||
) -> void:
|
||||
|
|
@ -372,6 +391,7 @@ func _set_horizontal_velocity_toward(
|
|||
dh = Vector3(1.0, 0.0, 0.0)
|
||||
else:
|
||||
dh = dh.normalized()
|
||||
dh = _walk_clamp_steering_reverse(dh)
|
||||
velocity = dh * MOVE_SPEED
|
||||
velocity.y = 0.0
|
||||
|
||||
|
|
@ -643,6 +663,7 @@ func _set_horizontal_velocity_from_nav_path_or_goal(fallback_goal_xz: Vector3) -
|
|||
if dir.dot(gh) < NAV_PATH_STEER_MIN_GOAL_DOT:
|
||||
_set_horizontal_velocity_toward(_auth_walk_goal, fallback_goal_xz)
|
||||
return
|
||||
dir = _walk_clamp_steering_reverse(dir)
|
||||
velocity = dir * MOVE_SPEED
|
||||
velocity.y = 0.0
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue