Implement first-person climbing mechanics in navigation controller

This commit is contained in:
2026-04-30 00:17:35 +02:00
parent 653f3f4d32
commit e38f0501b7

View File

@@ -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();