NS-23: harden bump departure (always skip nav on bump, steer dy<0)
- If any of three down-rays (body + two lower origins) hits ns19_bump, skip NavigationAgent waypoints unconditionally on that footprint. - Steering: any goal lower than origin with same xz (dy < 0) uses rim escape; dy in (-0.04, 0) previously zeroed velocity and could hang.pull/23/head
parent
66d7438a59
commit
35d16d15db
|
|
@ -1,7 +1,7 @@
|
|||
extends CharacterBody3D
|
||||
|
||||
## NS-23: Nav waypoints + stored server goal for arrival.
|
||||
## NS-19: `ns19_bump` — skip nav waypoints when leaving (goal lower) or on flatish bump top.
|
||||
## NS-19: any underfoot ray into `ns19_bump` → skip nav (waypoints); bumps are small vs obstacles.
|
||||
|
||||
const MOVE_SPEED: float = 5.0
|
||||
const ARRIVE_EPS: float = 0.35
|
||||
|
|
@ -11,11 +11,9 @@ const VERT_ARRIVE_EPS: float = 0.055
|
|||
const MAX_CLIMB_SPEED: float = 2.6
|
||||
const MAX_DESCENT_SPEED: float = 2.2
|
||||
const DIRECT_APPROACH_RADIUS: float = 0.85
|
||||
## Plateau / near-rim: floor normal within ~15° of up still counts (0.992 missed convex edges).
|
||||
const NS19_BUMP_FLAT_NORMAL_DOT: float = 0.964
|
||||
const NS19_RAY_DOWN: float = 3.0
|
||||
## Second ray origin offset toward feet so a tall capsule still hits bump underfoot.
|
||||
const NS19_FEET_RAY_Y_OFFSET: float = -0.45
|
||||
## Downward ray origins (Y offset from body origin) so we still detect bump under a tall capsule.
|
||||
const NS19_UNDERFOOT_RAY_Y: Array[float] = [0.0, -0.45, -0.82]
|
||||
|
||||
var _has_walk_goal: bool = false
|
||||
var _auth_walk_goal: Vector3 = Vector3.ZERO
|
||||
|
|
@ -47,16 +45,9 @@ func snap_to_server(world_pos: Vector3) -> void:
|
|||
|
||||
|
||||
func _should_skip_nav_for_ns19_bump() -> bool:
|
||||
var under_bump: bool = _ns19_bump_under_ray(global_position)
|
||||
if not under_bump:
|
||||
under_bump = _ns19_bump_under_ray(global_position + Vector3(0.0, NS19_FEET_RAY_Y_OFFSET, 0.0))
|
||||
if not under_bump:
|
||||
return false
|
||||
# Waypoints pick “down the mesh” first; horizontal steer to goal fixes departure.
|
||||
if _auth_walk_goal.y < global_position.y - 0.02:
|
||||
return true
|
||||
if is_on_floor() and get_floor_normal().dot(Vector3.UP) >= NS19_BUMP_FLAT_NORMAL_DOT:
|
||||
return true
|
||||
for y_off: float in NS19_UNDERFOOT_RAY_Y:
|
||||
if _ns19_bump_under_ray(global_position + Vector3(0.0, y_off, 0.0)):
|
||||
return true
|
||||
return false
|
||||
|
||||
|
||||
|
|
@ -96,8 +87,8 @@ func _steer_toward_world_point(point: Vector3) -> void:
|
|||
var desired: Vector3 = delta.normalized() * MOVE_SPEED
|
||||
desired.y = clampf(desired.y, -MAX_DESCENT_SPEED, MAX_CLIMB_SPEED)
|
||||
velocity = desired
|
||||
elif dy < -0.04:
|
||||
# Goal is lower and almost same xz (e.g. floor under the plateau): still need rim escape.
|
||||
elif dy < 0.0:
|
||||
# Same xz, goal slightly lower (e.g. -0.03): old threshold left velocity at zero (“hang”).
|
||||
var escape_h := Vector3(-global_transform.basis.z.x, 0.0, -global_transform.basis.z.z)
|
||||
if escape_h.length_squared() < 1e-8:
|
||||
escape_h = Vector3(1.0, 0.0, 0.0)
|
||||
|
|
@ -131,7 +122,7 @@ func _physics_process(_delta: float) -> void:
|
|||
move_and_slide()
|
||||
return
|
||||
|
||||
# On bump + (goal lower or flat top): skip waypoints so we do not follow vertical “drop” legs.
|
||||
# On bump: skip nav waypoints (drop-first paths); bump area is small vs the obstacle.
|
||||
if _should_skip_nav_for_ns19_bump():
|
||||
_steer_toward_world_point(_auth_walk_goal)
|
||||
move_and_slide()
|
||||
|
|
|
|||
Loading…
Reference in New Issue