diff --git a/src/runtime-three/third-person-navigation-controller.ts b/src/runtime-three/third-person-navigation-controller.ts index 45aa068d..45edfb6b 100644 --- a/src/runtime-three/third-person-navigation-controller.ts +++ b/src/runtime-three/third-person-navigation-controller.ts @@ -1273,6 +1273,47 @@ export class ThirdPersonNavigationController implements NavigationController { } }) : null; + + if ( + climbTopOutAssist === null && + playerMovement.edgeAssist.enabled && + climbMovement.motion.y > 0 + ) { + const climbLedgeGrabTarget = resolvePlayerLedgeGrabTarget({ + feetPosition: this.feetPosition, + shape: this.standingPlayerShape, + direction: { + x: -activeSurface.normal.x, + y: 0, + z: -activeSurface.normal.z + }, + pushToTopHeight: playerMovement.edgeAssist.pushToTopHeight, + canOccupyShape: (feetPosition, shape) => + this.context?.canOccupyPlayerShape?.(feetPosition, shape) ?? true, + probeGround: (feetPosition, shape, maxDistance) => + this.context?.probePlayerGround?.( + feetPosition, + shape, + maxDistance + ) ?? { + grounded: false, + distance: null, + normal: null, + slopeDegrees: null + } + }); + + if (climbLedgeGrabTarget !== null) { + this.enterLedgeGrab( + climbLedgeGrabTarget, + climbMovement.inputMagnitude + ); + this.updateCameraTransform(dt); + this.publishTelemetry(); + return true; + } + } + this.climbSurface = climbTopOutAssist === null ? activeSurface : null; const resolvedMotion =