You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Three Fiber玩家静止3秒后无法移动问题求助

问题分析与解决方案

核心问题

  1. Rapier刚体休眠机制:默认情况下,Rapier的动态刚体在静止3秒后会进入休眠状态,休眠后的刚体不会响应setLinvel等物理操作,导致玩家无法移动。
  2. 零向量归一化错误:当玩家停止输入时,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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 17:04:55