diff --git a/src/runtime-three/rapier-collision-world.ts b/src/runtime-three/rapier-collision-world.ts index 633d942f..2b7b54c5 100644 --- a/src/runtime-three/rapier-collision-world.ts +++ b/src/runtime-three/rapier-collision-world.ts @@ -380,6 +380,10 @@ export class RapierCollisionWorld { characterController, playerCollider, Math.max(CHARACTER_CONTROLLER_SNAP_TO_GROUND_DISTANCE, maxStepHeight), + maxStepHeight > COLLISION_EPSILON ? maxStepHeight : null, + maxStepHeight > COLLISION_EPSILON + ? maxStepHeight * AUTOSTEP_MIN_WIDTH_FACTOR + : null, playerShape.mode === "none" ? null : getFirstPersonPlayerShapeSignature(playerShape) @@ -391,6 +395,8 @@ export class RapierCollisionWorld { private readonly characterController: RAPIER.KinematicCharacterController | null, private readonly playerCollider: RAPIER.Collider | null, private readonly snapToGroundDistance: number, + private readonly autostepHeight: number | null, + private readonly autostepMinWidth: number | null, private currentPlayerShapeSignature: string | null ) {} @@ -448,11 +454,25 @@ export class RapierCollisionWorld { const currentCenter = feetPositionToColliderCenter(feetPosition, shape); this.playerCollider.setTranslation(currentCenter); const snapToGroundWasEnabled = this.characterController.snapToGroundEnabled(); + const autostepWasEnabled = + this.autostepHeight !== null && + this.autostepMinWidth !== null && + this.characterController.autostepEnabled(); + const supportProbe = this.probePlayerGround( + feetPosition, + shape, + this.snapToGroundDistance + ); + const supportGrounded = supportProbe.grounded; if (motion.y > COLLISION_EPSILON && snapToGroundWasEnabled) { this.characterController.disableSnapToGround(); } + if (!supportGrounded && autostepWasEnabled) { + this.characterController.disableAutostep(); + } + this.characterController.computeColliderMovement(this.playerCollider, motion); if (snapToGroundWasEnabled) { @@ -461,6 +481,14 @@ export class RapierCollisionWorld { ); } + if (autostepWasEnabled) { + this.characterController.enableAutostep( + this.autostepHeight, + this.autostepMinWidth, + false + ); + } + const correctedMovement = this.characterController.computedMovement(); const collidedAxes = { x: Math.abs(correctedMovement.x - motion.x) > COLLISION_EPSILON,