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
|
## tangentially → [code]horiz_dist[/code] crosses the radius → direct vs path
|
||||||
## alternates → velocity sign flips (Jolt ping-pong while [code]has_goal[/code]).
|
## 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_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]
|
## 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
|
## 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.
|
## (`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
|
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.
|
## 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
|
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
|
## 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
|
## (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).
|
## 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
|
_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(
|
func _set_horizontal_velocity_toward(
|
||||||
point: Vector3, fallback_dir_xz: Vector3 = Vector3.ZERO
|
point: Vector3, fallback_dir_xz: Vector3 = Vector3.ZERO
|
||||||
) -> void:
|
) -> void:
|
||||||
|
|
@ -372,6 +391,7 @@ func _set_horizontal_velocity_toward(
|
||||||
dh = Vector3(1.0, 0.0, 0.0)
|
dh = Vector3(1.0, 0.0, 0.0)
|
||||||
else:
|
else:
|
||||||
dh = dh.normalized()
|
dh = dh.normalized()
|
||||||
|
dh = _walk_clamp_steering_reverse(dh)
|
||||||
velocity = dh * MOVE_SPEED
|
velocity = dh * MOVE_SPEED
|
||||||
velocity.y = 0.0
|
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:
|
if dir.dot(gh) < NAV_PATH_STEER_MIN_GOAL_DOT:
|
||||||
_set_horizontal_velocity_toward(_auth_walk_goal, fallback_goal_xz)
|
_set_horizontal_velocity_toward(_auth_walk_goal, fallback_goal_xz)
|
||||||
return
|
return
|
||||||
|
dir = _walk_clamp_steering_reverse(dir)
|
||||||
velocity = dir * MOVE_SPEED
|
velocity = dir * MOVE_SPEED
|
||||||
velocity.y = 0.0
|
velocity.y = 0.0
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue