NEON-29: Hysteresis for nav column steering (walk ping-pong)
Single-radius switch at DIRECT_APPROACH_RADIUS let horiz_dist cross every frame between direct-to-goal and nav-path steering, flipping velocity ~180°. Schmitt band NAV_COLUMN_STEER_ENTER/EXIT with latched _walk_nav_column_steering; reset on new goal, snap, arrival, clear.pull/41/head
parent
0f4c23b815
commit
ff6c337e1d
|
|
@ -16,6 +16,12 @@ const FLOOR_ANGLE_LOOSE_TICKS_AFTER_STOP: int = 96
|
|||
const ARRIVE_EPS: float = 0.35
|
||||
const VERT_ARRIVE_EPS: float = 0.055
|
||||
const DIRECT_APPROACH_RADIUS: float = 0.85
|
||||
## Hysteresis for nav-path column steering (see `_physics_process`). At exactly
|
||||
## [member DIRECT_APPROACH_RADIUS] the old test flipped every frame: path nudges
|
||||
## 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 FLOOR_SNAP_MOVING: float = 0.32
|
||||
## Idle floor snap length (stronger to pin rim contacts).
|
||||
const FLOOR_SNAP_IDLE: float = 0.11
|
||||
|
|
@ -76,6 +82,8 @@ var _debug_last_idle_xz: Vector2 = Vector2.INF
|
|||
var _debug_idle_heartbeat: int = 0
|
||||
var _debug_last_transform_xz: Vector2 = Vector2.INF
|
||||
var _debug_trace_frame: int = 0
|
||||
## True while we use [method _set_horizontal_velocity_from_nav_path_or_goal] for vertical routing.
|
||||
var _walk_nav_column_steering: bool = false
|
||||
@onready var _nav_agent: NavigationAgent3D = $NavigationAgent3D
|
||||
|
||||
|
||||
|
|
@ -95,6 +103,7 @@ func set_authoritative_nav_goal(world_pos: Vector3) -> void:
|
|||
_step_assist_active = false
|
||||
_idle_anchor_active = false
|
||||
_idle_manual_correction_ticks = 0
|
||||
_walk_nav_column_steering = false
|
||||
_nav_agent.set_target_position(world_pos)
|
||||
|
||||
|
||||
|
|
@ -105,6 +114,7 @@ func clear_nav_goal() -> void:
|
|||
_step_assist_active = false
|
||||
_idle_anchor_active = false
|
||||
_idle_manual_correction_ticks = 0
|
||||
_walk_nav_column_steering = false
|
||||
_nav_agent.set_target_position(global_position)
|
||||
|
||||
|
||||
|
|
@ -141,6 +151,7 @@ func snap_to_server(world_pos: Vector3) -> void:
|
|||
_step_assist_active = false
|
||||
_idle_anchor_active = false
|
||||
_idle_manual_correction_ticks = 0
|
||||
_walk_nav_column_steering = false
|
||||
_nav_agent.set_target_position(settled)
|
||||
reset_physics_interpolation()
|
||||
|
||||
|
|
@ -674,6 +685,7 @@ func _physics_process(delta: float) -> void:
|
|||
_step_assist_active = false
|
||||
_idle_anchor_active = false
|
||||
_idle_manual_correction_ticks = 0
|
||||
_walk_nav_column_steering = false
|
||||
_nav_agent.set_target_position(global_position)
|
||||
_physics_idle_tick(delta)
|
||||
if _stable_idle_support():
|
||||
|
|
@ -708,7 +720,13 @@ func _physics_process(delta: float) -> void:
|
|||
_auth_walk_goal.y > feet_y + DESCEND_GOAL_Y_MARGIN
|
||||
or _auth_walk_goal.y < feet_y - DESCEND_GOAL_Y_MARGIN
|
||||
)
|
||||
if needs_vertical_routing and horiz_dist <= DIRECT_APPROACH_RADIUS:
|
||||
if not needs_vertical_routing:
|
||||
_walk_nav_column_steering = false
|
||||
elif horiz_dist <= NAV_COLUMN_STEER_ENTER_DIST:
|
||||
_walk_nav_column_steering = true
|
||||
elif horiz_dist >= NAV_COLUMN_STEER_EXIT_DIST:
|
||||
_walk_nav_column_steering = false
|
||||
if needs_vertical_routing and _walk_nav_column_steering:
|
||||
_set_horizontal_velocity_from_nav_path_or_goal(want_goal_h)
|
||||
else:
|
||||
_set_horizontal_velocity_toward(_auth_walk_goal, want_goal_h)
|
||||
|
|
|
|||
Loading…
Reference in New Issue