NEON-29: Idle gravity + snap when airborne (ledge / step drop)
_physics_idle_tick zeroed velocity with no gravity, so after walking off a terrace or arriving slightly above the floor FLOOR_SNAP_IDLE could not reach the ground and the body hovered until a new walk goal. Apply get_gravity()*delta and FLOOR_SNAP_MOVING while !is_on_floor(). Budgeted idle branch now runs the same physics when airborne instead of returning without move_and_slide.pull/41/head
parent
6b471b2102
commit
2a25a24e0b
|
|
@ -279,9 +279,17 @@ static func vertical_arrival_error(
|
||||||
return absf(goal_y - capsule_feet_y(body_origin_y, capsule_half_height))
|
return absf(goal_y - capsule_feet_y(body_origin_y, capsule_half_height))
|
||||||
|
|
||||||
|
|
||||||
func _physics_idle_tick() -> void:
|
func _physics_idle_tick(delta: float) -> void:
|
||||||
velocity = Vector3.ZERO
|
if is_on_floor():
|
||||||
floor_snap_length = FLOOR_SNAP_IDLE
|
velocity = Vector3.ZERO
|
||||||
|
floor_snap_length = FLOOR_SNAP_IDLE
|
||||||
|
else:
|
||||||
|
# Ledge / post-arrival hover: without gravity, vy stays 0 and FLOOR_SNAP_IDLE (0.11 m)
|
||||||
|
# cannot reach the lower floor — the capsule idles in mid-air until a new walk goal runs.
|
||||||
|
velocity.x = 0.0
|
||||||
|
velocity.z = 0.0
|
||||||
|
velocity += get_gravity() * delta
|
||||||
|
floor_snap_length = FLOOR_SNAP_MOVING
|
||||||
move_and_slide()
|
move_and_slide()
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -535,17 +543,27 @@ func _physics_process(delta: float) -> void:
|
||||||
_snap_capsule_upright()
|
_snap_capsule_upright()
|
||||||
return
|
return
|
||||||
if _idle_manual_correction_ticks >= IDLE_MANUAL_CORRECTION_MAX_TICKS:
|
if _idle_manual_correction_ticks >= IDLE_MANUAL_CORRECTION_MAX_TICKS:
|
||||||
velocity = Vector3.ZERO
|
if is_on_floor():
|
||||||
floor_snap_length = FLOOR_SNAP_IDLE
|
velocity = Vector3.ZERO
|
||||||
|
floor_snap_length = FLOOR_SNAP_IDLE
|
||||||
|
if _floor_angle_loose_ticks > 0:
|
||||||
|
_floor_angle_loose_ticks -= 1
|
||||||
|
_hold_idle_anchor()
|
||||||
|
_debug_trace_idle_state("budgeted")
|
||||||
|
_debug_trace_transform("physics")
|
||||||
|
_snap_capsule_upright()
|
||||||
|
return
|
||||||
|
# Airborne: do not freeze XZ without a physics step — same mid-air hang as idle tick.
|
||||||
|
_idle_anchor_active = false
|
||||||
|
_physics_idle_tick(delta)
|
||||||
if _floor_angle_loose_ticks > 0:
|
if _floor_angle_loose_ticks > 0:
|
||||||
_floor_angle_loose_ticks -= 1
|
_floor_angle_loose_ticks -= 1
|
||||||
_hold_idle_anchor()
|
|
||||||
_debug_trace_idle_state("budgeted")
|
_debug_trace_idle_state("budgeted")
|
||||||
_debug_trace_transform("physics")
|
_debug_trace_transform("physics")
|
||||||
_snap_capsule_upright()
|
_snap_capsule_upright()
|
||||||
return
|
return
|
||||||
_idle_anchor_active = false
|
_idle_anchor_active = false
|
||||||
_physics_idle_tick()
|
_physics_idle_tick(delta)
|
||||||
if _apply_idle_manual_correction():
|
if _apply_idle_manual_correction():
|
||||||
_idle_manual_correction_ticks += 1
|
_idle_manual_correction_ticks += 1
|
||||||
else:
|
else:
|
||||||
|
|
@ -576,7 +594,7 @@ func _physics_process(delta: float) -> void:
|
||||||
_idle_anchor_active = false
|
_idle_anchor_active = false
|
||||||
_idle_manual_correction_ticks = 0
|
_idle_manual_correction_ticks = 0
|
||||||
_nav_agent.set_target_position(global_position)
|
_nav_agent.set_target_position(global_position)
|
||||||
_physics_idle_tick()
|
_physics_idle_tick(delta)
|
||||||
if _apply_idle_manual_correction():
|
if _apply_idle_manual_correction():
|
||||||
_idle_manual_correction_ticks += 1
|
_idle_manual_correction_ticks += 1
|
||||||
_debug_trace_transform("physics")
|
_debug_trace_transform("physics")
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue