From 472021e844e8bc75fcd63f629508918133a954f4 Mon Sep 17 00:00:00 2001 From: Victor Giers Date: Sat, 11 Apr 2026 19:04:04 +0200 Subject: [PATCH] Add snap-to-ground distance constant and adjust character controller logic --- src/runtime-three/rapier-collision-world.ts | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/runtime-three/rapier-collision-world.ts b/src/runtime-three/rapier-collision-world.ts index 67e47c56..3c953357 100644 --- a/src/runtime-three/rapier-collision-world.ts +++ b/src/runtime-three/rapier-collision-world.ts @@ -19,6 +19,7 @@ import { getFirstPersonPlayerShapeSignature } from "./player-collision"; import type { RuntimeBrushTriMeshCollider, RuntimeSceneCollider } from "./runtime-scene-build"; const CHARACTER_CONTROLLER_OFFSET = 0.01; +const CHARACTER_CONTROLLER_SNAP_TO_GROUND_DISTANCE = 0.2; const COLLISION_EPSILON = 1e-5; const CAMERA_COLLISION_EPSILON = 1e-3; const GROUND_NORMAL_Y_THRESHOLD = 0.45; @@ -347,7 +348,9 @@ export class RapierCollisionWorld { if (characterController !== null) { characterController.setUp({ x: 0, y: 1, z: 0 }); characterController.setSlideEnabled(true); - characterController.enableSnapToGround(0.2); + characterController.enableSnapToGround( + CHARACTER_CONTROLLER_SNAP_TO_GROUND_DISTANCE + ); characterController.enableAutostep(0.35, 0.15, false); characterController.setMaxSlopeClimbAngle(Math.PI * 0.45); characterController.setMinSlopeSlideAngle(Math.PI * 0.5); @@ -425,8 +428,20 @@ export class RapierCollisionWorld { const currentCenter = feetPositionToColliderCenter(feetPosition, shape); this.playerCollider.setTranslation(currentCenter); + const snapToGroundWasEnabled = this.characterController.snapToGroundEnabled(); + + if (motion.y > COLLISION_EPSILON && snapToGroundWasEnabled) { + this.characterController.disableSnapToGround(); + } + this.characterController.computeColliderMovement(this.playerCollider, motion); + if (snapToGroundWasEnabled) { + this.characterController.enableSnapToGround( + CHARACTER_CONTROLLER_SNAP_TO_GROUND_DISTANCE + ); + } + const correctedMovement = this.characterController.computedMovement(); const collidedAxes = { x: Math.abs(correctedMovement.x - motion.x) > COLLISION_EPSILON,