NS-23: bump step-off bypass using floor-under-feet, not body Y
Ray down for floor Y under the capsule; skip nav only when goal is a bit lower than that surface, drop ≤0.55 m, and horiz ≤1.05 m. Matches leaving a bump without comparing pick/body origin (which broke obstacle pathing). Long crosses still use waypoints.pull/23/head
parent
72eef09d15
commit
8b2b64a326
|
|
@ -6,12 +6,16 @@ extends CharacterBody3D
|
||||||
## and steps comes from `move_and_slide` + floor_* on CharacterBody3D. Move **legality** (step,
|
## and steps comes from `move_and_slide` + floor_* on CharacterBody3D. Move **legality** (step,
|
||||||
## distance, bounds) is server MoveCommand only — not reimplemented here.
|
## distance, bounds) is server MoveCommand only — not reimplemented here.
|
||||||
##
|
##
|
||||||
## Nav for detours; if next waypoint has almost no xz offset, steer xz toward goal.
|
## Nav for detours; short local step-down (feet vs goal Y, not body origin) may bypass waypoints.
|
||||||
|
|
||||||
const MOVE_SPEED: float = 5.0
|
const MOVE_SPEED: float = 5.0
|
||||||
const ARRIVE_EPS: float = 0.35
|
const ARRIVE_EPS: float = 0.35
|
||||||
const VERT_ARRIVE_EPS: float = 0.055
|
const VERT_ARRIVE_EPS: float = 0.055
|
||||||
const DIRECT_APPROACH_RADIUS: float = 0.85
|
const DIRECT_APPROACH_RADIUS: float = 0.85
|
||||||
|
const FLOOR_PROBE_DOWN: float = 4.0
|
||||||
|
const STEP_OFF_FLOOR_MARGIN: float = 0.04
|
||||||
|
const STEP_OFF_MAX_DROP: float = 0.55
|
||||||
|
const STEP_OFF_MAX_HORIZ: float = 1.05
|
||||||
|
|
||||||
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
|
||||||
|
|
@ -42,6 +46,37 @@ func snap_to_server(world_pos: Vector3) -> void:
|
||||||
_nav_agent.set_target_position(world_pos)
|
_nav_agent.set_target_position(world_pos)
|
||||||
|
|
||||||
|
|
||||||
|
func _floor_y_under_body() -> float:
|
||||||
|
var space: PhysicsDirectSpaceState3D = get_world_3d().direct_space_state
|
||||||
|
var from: Vector3 = global_position
|
||||||
|
var to: Vector3 = from + Vector3(0.0, -FLOOR_PROBE_DOWN, 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 global_position.y
|
||||||
|
var pv: Variant = hit.get("position")
|
||||||
|
if pv is Vector3:
|
||||||
|
return (pv as Vector3).y
|
||||||
|
return global_position.y
|
||||||
|
|
||||||
|
|
||||||
|
func _nav_short_step_down_use_goal_direct() -> bool:
|
||||||
|
var floor_y: float = _floor_y_under_body()
|
||||||
|
if _auth_walk_goal.y >= floor_y - STEP_OFF_FLOOR_MARGIN:
|
||||||
|
return false
|
||||||
|
var drop: float = floor_y - _auth_walk_goal.y
|
||||||
|
if drop > STEP_OFF_MAX_DROP:
|
||||||
|
return false
|
||||||
|
var hd: float = Vector2(
|
||||||
|
_auth_walk_goal.x - global_position.x, _auth_walk_goal.z - global_position.z
|
||||||
|
).length()
|
||||||
|
if hd > STEP_OFF_MAX_HORIZ:
|
||||||
|
return false
|
||||||
|
return true
|
||||||
|
|
||||||
|
|
||||||
func _set_horizontal_velocity_toward(point: Vector3) -> void:
|
func _set_horizontal_velocity_toward(point: Vector3) -> void:
|
||||||
var pos := global_position
|
var pos := global_position
|
||||||
var dh: Vector3 = Vector3(point.x - pos.x, 0.0, point.z - pos.z)
|
var dh: Vector3 = Vector3(point.x - pos.x, 0.0, point.z - pos.z)
|
||||||
|
|
@ -73,6 +108,11 @@ func _physics_process(_delta: float) -> void:
|
||||||
move_and_slide()
|
move_and_slide()
|
||||||
return
|
return
|
||||||
|
|
||||||
|
if _nav_short_step_down_use_goal_direct():
|
||||||
|
_set_horizontal_velocity_toward(_auth_walk_goal)
|
||||||
|
move_and_slide()
|
||||||
|
return
|
||||||
|
|
||||||
if horiz_dist <= DIRECT_APPROACH_RADIUS:
|
if horiz_dist <= DIRECT_APPROACH_RADIUS:
|
||||||
_set_horizontal_velocity_toward(_auth_walk_goal)
|
_set_horizontal_velocity_toward(_auth_walk_goal)
|
||||||
else:
|
else:
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue