auto-git:
[change] src/runtime-three/player-climbing.ts
This commit is contained in:
@@ -14,6 +14,8 @@ import type {
|
|||||||
} from "./runtime-scene-build";
|
} from "./runtime-scene-build";
|
||||||
|
|
||||||
export const CLIMB_INPUT_ACTIVE_THRESHOLD = 0.5;
|
export const CLIMB_INPUT_ACTIVE_THRESHOLD = 0.5;
|
||||||
|
export const CLIMB_AUTO_LATCH_INPUT_THRESHOLD = 0.25;
|
||||||
|
export const CLIMB_AUTO_LATCH_MIN_INTO_SURFACE_DOT = 0.35;
|
||||||
export const CLIMB_SPEED_METERS_PER_SECOND = 2.4;
|
export const CLIMB_SPEED_METERS_PER_SECOND = 2.4;
|
||||||
export const CLIMB_DETECT_DISTANCE_METERS = 0.85;
|
export const CLIMB_DETECT_DISTANCE_METERS = 0.85;
|
||||||
export const CLIMB_KEEP_DISTANCE_METERS = 1.05;
|
export const CLIMB_KEEP_DISTANCE_METERS = 1.05;
|
||||||
@@ -187,25 +189,97 @@ export function isClimbableWallNormal(normal: Vec3): boolean {
|
|||||||
|
|
||||||
export function shouldEnterClimbing(options: {
|
export function shouldEnterClimbing(options: {
|
||||||
climbInput: number;
|
climbInput: number;
|
||||||
|
movementIntoSurface: boolean;
|
||||||
surface: RuntimePlayerClimbSurface | null;
|
surface: RuntimePlayerClimbSurface | null;
|
||||||
jumpPressed: boolean;
|
jumpPressed: boolean;
|
||||||
}): boolean {
|
}): boolean {
|
||||||
return (
|
return (
|
||||||
options.climbInput > CLIMB_INPUT_ACTIVE_THRESHOLD &&
|
|
||||||
options.surface !== null &&
|
options.surface !== null &&
|
||||||
!options.jumpPressed
|
!options.jumpPressed &&
|
||||||
|
(options.climbInput > CLIMB_INPUT_ACTIVE_THRESHOLD ||
|
||||||
|
options.movementIntoSurface)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function shouldExitClimbing(options: {
|
export function shouldExitClimbing(options: {
|
||||||
climbInput: number;
|
|
||||||
surface: RuntimePlayerClimbSurface | null;
|
surface: RuntimePlayerClimbSurface | null;
|
||||||
jumpPressed: boolean;
|
jumpPressed: boolean;
|
||||||
}): boolean {
|
}): boolean {
|
||||||
|
return options.surface === null || options.jumpPressed;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function resolveClimbPlanarInputDirection(
|
||||||
|
input: PlayerStartActionInputState,
|
||||||
|
movementYawRadians: number
|
||||||
|
): { direction: Vec3 | null; inputMagnitude: number } {
|
||||||
|
const inputX = input.moveRight - input.moveLeft;
|
||||||
|
const inputZ = input.moveForward - input.moveBackward;
|
||||||
|
const rawMagnitude = Math.hypot(inputX, inputZ);
|
||||||
|
const inputMagnitude = Math.min(1, rawMagnitude);
|
||||||
|
|
||||||
|
if (rawMagnitude <= VECTOR_EPSILON) {
|
||||||
|
return {
|
||||||
|
direction: null,
|
||||||
|
inputMagnitude
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const normalizedInputX = inputX / rawMagnitude;
|
||||||
|
const normalizedInputZ = inputZ / rawMagnitude;
|
||||||
|
const forwardX = Math.sin(movementYawRadians);
|
||||||
|
const forwardZ = Math.cos(movementYawRadians);
|
||||||
|
const rightX = -Math.cos(movementYawRadians);
|
||||||
|
const rightZ = Math.sin(movementYawRadians);
|
||||||
|
const directionX =
|
||||||
|
forwardX * normalizedInputZ + rightX * normalizedInputX;
|
||||||
|
const directionZ =
|
||||||
|
forwardZ * normalizedInputZ + rightZ * normalizedInputX;
|
||||||
|
const directionMagnitude = Math.hypot(directionX, directionZ);
|
||||||
|
|
||||||
|
if (directionMagnitude <= VECTOR_EPSILON) {
|
||||||
|
return {
|
||||||
|
direction: null,
|
||||||
|
inputMagnitude
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
direction: {
|
||||||
|
x: directionX / directionMagnitude,
|
||||||
|
y: 0,
|
||||||
|
z: directionZ / directionMagnitude
|
||||||
|
},
|
||||||
|
inputMagnitude
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function isClimbMovementIntoSurface(options: {
|
||||||
|
input: PlayerStartActionInputState;
|
||||||
|
movementYawRadians: number;
|
||||||
|
surface: RuntimePlayerClimbSurface | null;
|
||||||
|
}): boolean {
|
||||||
|
if (options.surface === null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const inputDirection = resolveClimbPlanarInputDirection(
|
||||||
|
options.input,
|
||||||
|
options.movementYawRadians
|
||||||
|
);
|
||||||
|
|
||||||
|
if (
|
||||||
|
inputDirection.direction === null ||
|
||||||
|
inputDirection.inputMagnitude < CLIMB_AUTO_LATCH_INPUT_THRESHOLD
|
||||||
|
) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const normal = normalizeVec3(options.surface.normal);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
options.climbInput <= CLIMB_INPUT_ACTIVE_THRESHOLD ||
|
normal !== null &&
|
||||||
options.surface === null ||
|
dotVec3(inputDirection.direction, normal) <=
|
||||||
options.jumpPressed
|
-CLIMB_AUTO_LATCH_MIN_INTO_SURFACE_DOT
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user