React Three Fiber玩家静止3秒后无法移动问题求助
问题分析与解决方案
核心问题
- Rapier刚体休眠机制:默认情况下,Rapier的动态刚体在静止3秒后会进入休眠状态,休眠后的刚体不会响应
setLinvel等物理操作,导致玩家无法移动。 - 零向量归一化错误:当玩家停止输入时,
direction向量为零向量,调用normalize()会生成NaN,导致刚体速度异常,进一步加剧移动失效问题。
具体修复步骤
1. 禁用刚体休眠
在Player.jsx的RigidBody组件中添加sleepThreshold={0}属性,彻底关闭休眠机制:
<RigidBody ref={playerRef} colliders={false} mass={1} type="dynamic" position={[2, 2, 0]} enabledRotations={[false, false, false]} sleepThreshold={0} // 禁用刚体休眠 onCollisionEnter={(e) => { // 原有碰撞逻辑 }}>
2. 修复零向量归一化问题
修改useFrame中的方向计算逻辑,避免对零向量执行归一化操作:
useFrame((state) => { const velocity = playerRef.current.linvel() const { forward, backward, left, right, jump, crouch } = get() const translation = playerRef.current.translation(); state.camera.position.set(translation.x, translation.y, translation.z); frontVector.set(0, 0, backward - forward) sideVector.set(left - right, 0, 0) direction.subVectors(frontVector, sideVector) // 仅当向量长度大于0时才归一化,避免NaN if (direction.lengthSq() > 0) { direction.normalize().multiplyScalar(SPEED) } else { // 无输入时重置方向向量 direction.set(0, 0, 0) } direction.applyEuler(state.camera.rotation) playerRef.current.setLinvel({ x: direction.x, y: velocity.y, z: direction.z }) })
可选优化:按需唤醒刚体(保留休眠机制)
如果希望保留休眠以优化性能,可以在检测到用户输入时手动唤醒刚体:
useFrame((state) => { const velocity = playerRef.current.linvel() const { forward, backward, left, right, jump, crouch } = get() const translation = playerRef.current.translation(); state.camera.position.set(translation.x, translation.y, translation.z); // 检测是否有用户输入,如有则唤醒刚体 const hasInput = forward || backward || left || right || jump || crouch if (hasInput) { playerRef.current.wakeUp() } // 后续方向计算逻辑... })
内容的提问来源于stack exchange,提问作者Antonio Turner
相关产品推荐
相关产品推荐

