Enhance climbing mechanics with detailed input and surface detection
This commit is contained in:
@@ -15,6 +15,8 @@ import {
|
||||
CLIMB_INPUT_ACTIVE_THRESHOLD,
|
||||
CLIMB_SPEED_METERS_PER_SECOND,
|
||||
computeClimbPlaneMovement,
|
||||
isClimbMovementIntoSurface,
|
||||
resolveClimbPlanarInputDirection,
|
||||
shouldEnterClimbing,
|
||||
shouldExitClimbing,
|
||||
type RuntimePlayerClimbSurface
|
||||
@@ -425,7 +427,10 @@ export class FirstPersonNavigationController implements NavigationController {
|
||||
this.publishTelemetry();
|
||||
}
|
||||
|
||||
private resolveClimbProbeDirection(movementYawRadians: number): Vec3 {
|
||||
private resolveClimbProbeDirection(
|
||||
movementYawRadians: number,
|
||||
inputState: ReturnType<typeof resolvePlayerStartActionInputs>
|
||||
): Vec3 {
|
||||
if (this.climbSurface !== null) {
|
||||
return {
|
||||
x: -this.climbSurface.normal.x,
|
||||
@@ -434,6 +439,15 @@ export class FirstPersonNavigationController implements NavigationController {
|
||||
};
|
||||
}
|
||||
|
||||
const inputDirection = resolveClimbPlanarInputDirection(
|
||||
inputState,
|
||||
movementYawRadians
|
||||
);
|
||||
|
||||
if (inputDirection.direction !== null) {
|
||||
return inputDirection.direction;
|
||||
}
|
||||
|
||||
return {
|
||||
x: Math.sin(movementYawRadians),
|
||||
y: 0,
|
||||
@@ -491,22 +505,27 @@ export class FirstPersonNavigationController implements NavigationController {
|
||||
const climbPressed = inputState.climb > CLIMB_INPUT_ACTIVE_THRESHOLD;
|
||||
const jumpPressed = inputState.jump > CLIMB_INPUT_ACTIVE_THRESHOLD;
|
||||
|
||||
if (!climbPressed) {
|
||||
this.climbLatchBlocked = false;
|
||||
}
|
||||
|
||||
const climbSurface =
|
||||
this.context.resolvePlayerClimbSurface?.(
|
||||
this.feetPosition,
|
||||
this.resolveClimbProbeDirection(movementYawRadians),
|
||||
this.resolveClimbProbeDirection(movementYawRadians, inputState),
|
||||
this.standingPlayerShape,
|
||||
this.climbSurface
|
||||
) ?? null;
|
||||
const movementIntoSurface = isClimbMovementIntoSurface({
|
||||
input: inputState,
|
||||
movementYawRadians,
|
||||
surface: climbSurface
|
||||
});
|
||||
const climbIntentActive = climbPressed || movementIntoSurface;
|
||||
|
||||
if (!climbIntentActive) {
|
||||
this.climbLatchBlocked = false;
|
||||
}
|
||||
|
||||
if (
|
||||
this.climbSurface !== null &&
|
||||
shouldExitClimbing({
|
||||
climbInput: inputState.climb,
|
||||
surface: climbSurface,
|
||||
jumpPressed
|
||||
})
|
||||
@@ -572,10 +591,6 @@ export class FirstPersonNavigationController implements NavigationController {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (climbSurface === null && climbPressed) {
|
||||
this.climbLatchBlocked = true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -584,6 +599,7 @@ export class FirstPersonNavigationController implements NavigationController {
|
||||
(this.climbLatchBlocked ||
|
||||
!shouldEnterClimbing({
|
||||
climbInput: inputState.climb,
|
||||
movementIntoSurface,
|
||||
surface: climbSurface,
|
||||
jumpPressed
|
||||
}))
|
||||
|
||||
Reference in New Issue
Block a user