diff --git a/src/runtime-three/first-person-navigation-controller.ts b/src/runtime-three/first-person-navigation-controller.ts index 75cc31bd..53b22ca9 100644 --- a/src/runtime-three/first-person-navigation-controller.ts +++ b/src/runtime-three/first-person-navigation-controller.ts @@ -11,6 +11,14 @@ import { resolvePlayerStartActionInputs, resolvePlayerStartLookInput, } from "./player-input-bindings"; +import { + CLIMB_INPUT_ACTIVE_THRESHOLD, + CLIMB_SPEED_METERS_PER_SECOND, + computeClimbPlaneMovement, + shouldEnterClimbing, + shouldExitClimbing, + type RuntimePlayerClimbSurface +} from "./player-climbing"; import { createIdleRuntimeLocomotionState, stepPlayerLocomotion @@ -121,6 +129,8 @@ export class FirstPersonNavigationController implements NavigationController { private jumpBufferRemainingMs = 0; private coyoteTimeRemainingMs = 0; private jumpHoldRemainingMs = 0; + private climbSurface: RuntimePlayerClimbSurface | null = null; + private climbLatchBlocked = false; activate(ctx: RuntimeControllerContext): void { this.context = ctx; @@ -225,6 +235,8 @@ export class FirstPersonNavigationController implements NavigationController { this.jumpBufferRemainingMs = 0; this.coyoteTimeRemainingMs = 0; this.jumpHoldRemainingMs = 0; + this.climbSurface = null; + this.climbLatchBlocked = false; this.previousTelemetry = null; ctx.setRuntimeMessage(null); ctx.setPlayerControllerTelemetry(null); @@ -267,6 +279,8 @@ export class FirstPersonNavigationController implements NavigationController { this.jumpBufferRemainingMs = 0; this.coyoteTimeRemainingMs = 0; this.jumpHoldRemainingMs = 0; + this.climbSurface = null; + this.climbLatchBlocked = false; } update(dt: number): void { @@ -297,6 +311,12 @@ export class FirstPersonNavigationController implements NavigationController { ); } + if ( + this.stepClimbing(dt, inputState, playerMovement, this.yawRadians) + ) { + return; + } + const locomotionStep = stepPlayerLocomotion( { dt, @@ -397,6 +417,8 @@ export class FirstPersonNavigationController implements NavigationController { this.jumpBufferRemainingMs = 0; this.coyoteTimeRemainingMs = 0; this.jumpHoldRemainingMs = 0; + this.climbSurface = null; + this.climbLatchBlocked = false; this.inWaterVolume = false; this.inFogVolume = false; this.updateCameraTransform();