diff --git a/client/scripts/player.gd b/client/scripts/player.gd index 1fbbf4d..a99c0ce 100644 --- a/client/scripts/player.gd +++ b/client/scripts/player.gd @@ -85,6 +85,8 @@ const WALK_CONTINUATION_MAX_BELOW_FEET: float = 0.14 ## ~0.42 m: **TerracePlatformB** top (~0.6 m) → floor (0) qualifies; **TerraceStepB** (~0.3 m) → floor does ## not — shallow drops still rely on [method _walk_has_close_floor_probe_below]. const WALK_DEEP_DESCENT_FEET_ABOVE_GOAL: float = 0.42 +## [method get_gravity] can be ~0 with missing/odd project defaults; ledge peel + airborne walk still need a pull. +const WALK_FALLBACK_GRAVITY_Y: float = -9.81 ## CapsuleShape3D in scene: height = 1.0 (cylinder portion), radius = 0.4. ## Total half-height from body origin to physical bottom = 0.5 + 0.4 = 0.9 ## (`CAPSULE_HALF_HEIGHT + PLAYER_CAPSULE_RADIUS`). @@ -454,7 +456,7 @@ func _walk_has_close_floor_probe_below(move_dir_xz: Vector2) -> bool: ## velocity does **not** move the body off a terrace lip; use [method _apply_walk_post_slide_ledge_peel]. func _apply_walk_air_gravity(delta: float, _feet_y: float, _move_dir_xz: Vector2 = Vector2.ZERO) -> void: if not is_on_floor(): - velocity += get_gravity() * delta + velocity += _effective_gravity(delta) * delta ## After [method move_and_slide], peel the capsule down when the authoritative goal is below the feet @@ -479,8 +481,11 @@ func _apply_walk_post_slide_ledge_peel( if not peel: _walk_ledge_peel_vy = 0.0 return - _walk_ledge_peel_vy += get_gravity().y * delta - global_position.y += _walk_ledge_peel_vy * delta + _walk_ledge_peel_vy += _effective_gravity(delta).y * delta + var dy: float = _walk_ledge_peel_vy * delta + if absf(dy) > 1e-9: + # Raw [code]global_position[/code] edits can be ignored/overwritten vs Jolt sync after [method move_and_slide]. + move_and_collide(Vector3(0.0, dy, 0.0), false, safe_margin, false) func _walk_floor_snap_length( @@ -576,6 +581,13 @@ func _set_horizontal_velocity_from_nav_path_or_goal(fallback_goal_xz: Vector3) - velocity.y = 0.0 +func _effective_gravity(_delta: float) -> Vector3: + var g: Vector3 = get_gravity() + if g.length_squared() < 0.25: + return Vector3(0.0, WALK_FALLBACK_GRAVITY_Y, 0.0) + return g + + static func capsule_feet_y(body_origin_y: float, capsule_half_height: float) -> float: return body_origin_y - capsule_half_height @@ -595,7 +607,7 @@ func _physics_idle_tick(delta: float) -> void: # 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 + velocity += _effective_gravity(delta) * delta floor_snap_length = FLOOR_SNAP_MOVING move_and_slide()