From 38aa4bfcd53c0adce0081a494923f265b996e117 Mon Sep 17 00:00:00 2001 From: VinPropane Date: Sun, 5 Apr 2026 01:56:56 -0400 Subject: [PATCH] =?UTF-8?q?NS-23:=20Unstick=20bump=20rim=20=E2=80=94=20wal?= =?UTF-8?q?l=20peel=20+=20goal=20boost=20when=20descending?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Convex frustum sides turn goal steering into tangential rim slide with little net progress. When footprint still hits ns19_bump and dest floor is lower by at least STEP_OFF_MIN_DROP, add horizontal wall-normal push (if it does not strongly oppose goal) plus a small goal-direction boost, cap xz speed. Slightly raise STEP_OFF_DESCEND_SPEED for the step-off branch. --- client/scripts/player.gd | 48 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/client/scripts/player.gd b/client/scripts/player.gd index b8df20f..af0e337 100644 --- a/client/scripts/player.gd +++ b/client/scripts/player.gd @@ -25,7 +25,12 @@ const FLOOR_PROBE_BODY_Y_OFFSET: float = -0.55 ## Extra xz rays for step-off; max Y keeps bump support when center ray sees floor first. const STEP_FOOTPRINT_HALF: float = 0.2 ## Downward vy only while step-off bypass is active (not global gravity). -const STEP_OFF_DESCEND_SPEED: float = 1.6 +const STEP_OFF_DESCEND_SPEED: float = 2.2 +## Peel off frustum wall when sliding tangentially along the rim (m/s, added to xz velocity). +const BUMP_RIM_WALL_PUSH: float = 2.6 +## Extra push toward goal xz while on a wall in that rim case (m/s). +const BUMP_RIM_GOAL_BOOST: float = 1.15 +const BUMP_RIM_MAX_HORIZ_MULT: float = 1.38 ## If next waypoint is within this xz of us, steer to goal (rim / underfoot waypoints). const NEXT_WAYPOINT_MIN_HORIZ_SQ: float = 0.01 @@ -191,6 +196,44 @@ func _set_horizontal_velocity_toward(point: Vector3) -> void: velocity.y = 0.0 +func _departing_ns19_bump_to_lower_floor() -> bool: + var fp: Dictionary = _footprint_step_down_state() + if not bool(fp["touches_ns19_bump"]): + return false + var max_y: float = float(fp["max_y"]) + var dest_y: float = _destination_footing_y() + return max_y >= dest_y + STEP_OFF_MIN_DROP + + +## Frustum walls turn “toward goal” into tangential rim slide; nudge out + along goal, capped. +func _apply_bump_rim_wall_unstick() -> void: + if not _departing_ns19_bump_to_lower_floor(): + return + var pos: Vector3 = global_position + var to_g: Vector3 = Vector3(_auth_walk_goal.x - pos.x, 0.0, _auth_walk_goal.z - pos.z) + var lg: float = to_g.length_squared() + if lg < 1e-14: + return + to_g /= sqrt(lg) + if is_on_wall(): + var wn: Vector3 = get_wall_normal() + var wn_h: Vector3 = Vector3(wn.x, 0.0, wn.z) + var lw: float = wn_h.length_squared() + if lw > 1e-12: + wn_h /= sqrt(lw) + if wn_h.dot(to_g) >= -0.32: + velocity.x += wn_h.x * BUMP_RIM_WALL_PUSH + velocity.z += wn_h.z * BUMP_RIM_WALL_PUSH + velocity.x += to_g.x * BUMP_RIM_GOAL_BOOST + velocity.z += to_g.z * BUMP_RIM_GOAL_BOOST + var cap: float = MOVE_SPEED * BUMP_RIM_MAX_HORIZ_MULT + var h: Vector2 = Vector2(velocity.x, velocity.z) + if h.length_squared() > cap * cap: + h = h.normalized() * cap + velocity.x = h.x + velocity.z = h.y + + func _physics_process(_delta: float) -> void: if not _has_walk_goal: velocity = Vector3.ZERO @@ -216,12 +259,14 @@ func _physics_process(_delta: float) -> void: var nav_map: RID = _nav_agent.get_navigation_map() if NavigationServer3D.map_get_iteration_id(nav_map) == 0: _set_horizontal_velocity_toward(_auth_walk_goal) + _apply_bump_rim_wall_unstick() move_and_slide() return if _use_direct_step_down_steering(): _set_horizontal_velocity_toward(_auth_walk_goal) velocity.y = -STEP_OFF_DESCEND_SPEED + _apply_bump_rim_wall_unstick() move_and_slide() return @@ -237,4 +282,5 @@ func _physics_process(_delta: float) -> void: else: _set_horizontal_velocity_toward(_auth_walk_goal) + _apply_bump_rim_wall_unstick() move_and_slide()