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
|
extends CharacterBody3D
|
||||||
|
|
||||||
## NS-23: Nav waypoints + stored server goal for arrival.
|
## 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 MOVE_SPEED: float = 5.0
|
||||||
const ARRIVE_EPS: float = 0.35
|
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_CLIMB_SPEED: float = 2.6
|
||||||
const MAX_DESCENT_SPEED: float = 2.2
|
const MAX_DESCENT_SPEED: float = 2.2
|
||||||
const DIRECT_APPROACH_RADIUS: float = 0.85
|
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
|
const NS19_RAY_DOWN: float = 3.0
|
||||||
## Second ray origin offset toward feet so a tall capsule still hits bump underfoot.
|
## Downward ray origins (Y offset from body origin) so we still detect bump under a tall capsule.
|
||||||
const NS19_FEET_RAY_Y_OFFSET: float = -0.45
|
const NS19_UNDERFOOT_RAY_Y: Array[float] = [0.0, -0.45, -0.82]
|
||||||
|
|
||||||
var _has_walk_goal: bool = false
|
var _has_walk_goal: bool = false
|
||||||
var _auth_walk_goal: Vector3 = Vector3.ZERO
|
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:
|
func _should_skip_nav_for_ns19_bump() -> bool:
|
||||||
var under_bump: bool = _ns19_bump_under_ray(global_position)
|
for y_off: float in NS19_UNDERFOOT_RAY_Y:
|
||||||
if not under_bump:
|
if _ns19_bump_under_ray(global_position + Vector3(0.0, y_off, 0.0)):
|
||||||
under_bump = _ns19_bump_under_ray(global_position + Vector3(0.0, NS19_FEET_RAY_Y_OFFSET, 0.0))
|
return true
|
||||||
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
|
|
||||||
return false
|
return false
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -96,8 +87,8 @@ func _steer_toward_world_point(point: Vector3) -> void:
|
||||||
var desired: Vector3 = delta.normalized() * MOVE_SPEED
|
var desired: Vector3 = delta.normalized() * MOVE_SPEED
|
||||||
desired.y = clampf(desired.y, -MAX_DESCENT_SPEED, MAX_CLIMB_SPEED)
|
desired.y = clampf(desired.y, -MAX_DESCENT_SPEED, MAX_CLIMB_SPEED)
|
||||||
velocity = desired
|
velocity = desired
|
||||||
elif dy < -0.04:
|
elif dy < 0.0:
|
||||||
# Goal is lower and almost same xz (e.g. floor under the plateau): still need rim escape.
|
# 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)
|
var escape_h := Vector3(-global_transform.basis.z.x, 0.0, -global_transform.basis.z.z)
|
||||||
if escape_h.length_squared() < 1e-8:
|
if escape_h.length_squared() < 1e-8:
|
||||||
escape_h = Vector3(1.0, 0.0, 0.0)
|
escape_h = Vector3(1.0, 0.0, 0.0)
|
||||||
|
|
@ -131,7 +122,7 @@ func _physics_process(_delta: float) -> void:
|
||||||
move_and_slide()
|
move_and_slide()
|
||||||
return
|
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():
|
if _should_skip_nav_for_ns19_bump():
|
||||||
_steer_toward_world_point(_auth_walk_goal)
|
_steer_toward_world_point(_auth_walk_goal)
|
||||||
move_and_slide()
|
move_and_slide()
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue