NS-23: skip nav waypoints on NS-19 bump plateaus only
Restore obstacle routing via waypoints elsewhere; on bump tops nav often prefers a downward segment and breaks departure. Detect plateau with is_on_floor + flat normal + ray down into group ns19_bump; then steer only toward authoritative goal xz. Slopes keep waypoint pathing.pull/23/head
parent
a5ec8df4a7
commit
db1fe0f46b
|
|
@ -138,7 +138,7 @@ transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.95, 0.22, -1.05)
|
|||
mesh = SubResource("BoxMesh_marker")
|
||||
surface_material_override/0 = SubResource("Mat_marker_base")
|
||||
|
||||
[node name="NS19BumpA" type="StaticBody3D" parent="World/NavigationRegion3D" unique_id=1900001 groups=["walkable"]]
|
||||
[node name="NS19BumpA" type="StaticBody3D" parent="World/NavigationRegion3D" unique_id=1900001 groups=["walkable", "ns19_bump"]]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -3.4, 0.075, -2.6)
|
||||
collision_layer = 1
|
||||
|
||||
|
|
@ -149,7 +149,7 @@ surface_material_override/0 = SubResource("Mat_ns19_bump")
|
|||
[node name="CollisionShape3D" type="CollisionShape3D" parent="World/NavigationRegion3D/NS19BumpA" unique_id=1900003]
|
||||
shape = SubResource("Convex_ns19a_frustum")
|
||||
|
||||
[node name="NS19BumpB" type="StaticBody3D" parent="World/NavigationRegion3D" unique_id=1900011 groups=["walkable"]]
|
||||
[node name="NS19BumpB" type="StaticBody3D" parent="World/NavigationRegion3D" unique_id=1900011 groups=["walkable", "ns19_bump"]]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1.85, 0.06, -4.1)
|
||||
collision_layer = 1
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
extends CharacterBody3D
|
||||
|
||||
## NS-23: Nav waypoints + stored server goal for arrival.
|
||||
## NS-19: bump collision is one convex frustum (plateau + slopes); no autostep.
|
||||
## NS-19: convex frustum bumps; `ns19_bump` group — on flat plateau skip nav waypoints (departure).
|
||||
|
||||
const MOVE_SPEED: float = 5.0
|
||||
const ARRIVE_EPS: float = 0.35
|
||||
|
|
@ -11,6 +11,8 @@ 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
|
||||
|
||||
var _has_walk_goal: bool = false
|
||||
var _auth_walk_goal: Vector3 = Vector3.ZERO
|
||||
|
|
@ -41,6 +43,33 @@ 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():
|
||||
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)
|
||||
|
||||
|
||||
func _raycast_down_hits_group(group_name: String, cast_len: float) -> 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 q: PhysicsRayQueryParameters3D = PhysicsRayQueryParameters3D.create(from, to)
|
||||
q.collision_mask = 1
|
||||
q.exclude = [get_rid()]
|
||||
var hit: Dictionary = space.intersect_ray(q)
|
||||
if hit.is_empty():
|
||||
return false
|
||||
var col: Variant = hit.get("collider")
|
||||
var n: Node = col as Node
|
||||
while n:
|
||||
if n.is_in_group(group_name):
|
||||
return true
|
||||
n = n.get_parent()
|
||||
return false
|
||||
|
||||
|
||||
func _steer_toward_world_point(point: Vector3) -> void:
|
||||
var pos := global_position
|
||||
var delta_h: Vector3 = Vector3(point.x - pos.x, 0.0, point.z - pos.z)
|
||||
|
|
@ -94,6 +123,14 @@ 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():
|
||||
_steer_toward_world_point(_auth_walk_goal)
|
||||
move_and_slide()
|
||||
return
|
||||
|
||||
if horiz_dist <= DIRECT_APPROACH_RADIUS:
|
||||
_steer_toward_world_point(_auth_walk_goal)
|
||||
else:
|
||||
|
|
|
|||
Loading…
Reference in New Issue