NS-23: broaden NS-19 bump nav bypass for departure
Plateau-only (strict flat normal + is_on_floor) missed rim poses and convex top edges. Skip waypoints when a down ray from body or feet offset hits ns19_bump and either the goal is lower than the body origin (typical floor click off bump) or we are on a flatter floor normal (~15°). Keeps waypoint routing on bump slopes when climbing past obstacles unless the move is clearly downward.pull/23/head
parent
db1fe0f46b
commit
66d7438a59
|
|
@ -1,7 +1,7 @@
|
|||
extends CharacterBody3D
|
||||
|
||||
## NS-23: Nav waypoints + stored server goal for arrival.
|
||||
## NS-19: convex frustum bumps; `ns19_bump` group — on flat plateau skip nav waypoints (departure).
|
||||
## NS-19: `ns19_bump` — skip nav waypoints when leaving (goal lower) or on flatish bump top.
|
||||
|
||||
const MOVE_SPEED: float = 5.0
|
||||
const ARRIVE_EPS: float = 0.35
|
||||
|
|
@ -11,8 +11,11 @@ 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
|
||||
## Floor normal must be this “flat” to count as bump plateau (slopes use nav waypoints).
|
||||
const NS19_BUMP_TOP_NORMAL_DOT: float = 0.992
|
||||
## 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
|
||||
|
||||
var _has_walk_goal: bool = false
|
||||
var _auth_walk_goal: Vector3 = Vector3.ZERO
|
||||
|
|
@ -43,18 +46,23 @@ func snap_to_server(world_pos: Vector3) -> void:
|
|||
_nav_agent.set_target_position(world_pos)
|
||||
|
||||
|
||||
func _on_ns19_bump_plateau() -> bool:
|
||||
if not is_on_floor():
|
||||
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
|
||||
if get_floor_normal().dot(Vector3.UP) < NS19_BUMP_TOP_NORMAL_DOT:
|
||||
return false
|
||||
return _raycast_down_hits_group("ns19_bump", 2.5)
|
||||
# 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
|
||||
|
||||
|
||||
func _raycast_down_hits_group(group_name: String, cast_len: float) -> bool:
|
||||
func _ns19_bump_under_ray(from: Vector3) -> bool:
|
||||
var space: PhysicsDirectSpaceState3D = get_world_3d().direct_space_state
|
||||
var from: Vector3 = global_position
|
||||
var to: Vector3 = from + Vector3(0.0, -cast_len, 0.0)
|
||||
var to: Vector3 = from + Vector3(0.0, -NS19_RAY_DOWN, 0.0)
|
||||
var q: PhysicsRayQueryParameters3D = PhysicsRayQueryParameters3D.create(from, to)
|
||||
q.collision_mask = 1
|
||||
q.exclude = [get_rid()]
|
||||
|
|
@ -64,7 +72,7 @@ func _raycast_down_hits_group(group_name: String, cast_len: float) -> bool:
|
|||
var col: Variant = hit.get("collider")
|
||||
var n: Node = col as Node
|
||||
while n:
|
||||
if n.is_in_group(group_name):
|
||||
if n.is_in_group("ns19_bump"):
|
||||
return true
|
||||
n = n.get_parent()
|
||||
return false
|
||||
|
|
@ -123,10 +131,8 @@ func _physics_process(_delta: float) -> void:
|
|||
move_and_slide()
|
||||
return
|
||||
|
||||
# Nav waypoints on the plateau often point down the slope first; goal-only + horizontal steer
|
||||
# matches the NS-19 departure fix. Slopes stay on waypoints so obstacle routing still applies
|
||||
# when crossing the district.
|
||||
if _on_ns19_bump_plateau():
|
||||
# On bump + (goal lower or flat top): skip waypoints so we do not follow vertical “drop” legs.
|
||||
if _should_skip_nav_for_ns19_bump():
|
||||
_steer_toward_world_point(_auth_walk_goal)
|
||||
move_and_slide()
|
||||
return
|
||||
|
|
|
|||
Loading…
Reference in New Issue