首页 > 解决方案 > 反应三纤维如何控制人的运动?

问题描述

我想创建一个游戏,我必须通过键盘输入使我的模型可控。我不知道最好的方法是什么以及如何正确实施。

标签: react-three-fiber

解决方案


我们可以用 cannon.js 来实现它

  1. 创建一个自定义挂钩来监听用户的输入。
const usePersonControls = () => {
  const keys = {
    KeyW: 'forward',
    KeyS: 'backward',
    KeyA: 'left',
    KeyD: 'right',
    Space: 'jump',
  }

  const moveFieldByKey = (key) => keys[key]

  const [movement, setMovement] = useState({
    forward: false,
    backward: false,
    left: false,
    right: false,
    jump: false,
  })

  useEffect(() => {
    const handleKeyDown = (e) => {
      setMovement((m) => ({ ...m, [moveFieldByKey(e.code)]: true }))
    }
    const handleKeyUp = (e) => {
      setMovement((m) => ({ ...m, [moveFieldByKey(e.code)]: false }))
    }
    document.addEventListener('keydown', handleKeyDown)
    document.addEventListener('keyup', handleKeyUp)
    return () => {
      document.removeEventListener('keydown', handleKeyDown)
      document.removeEventListener('keyup', handleKeyUp)
    }
  }, [])
  return movement
}

现在像这样使用它,

const { forward, backward, left, right, jump } = usePersonControls()
  1. 在 Cannon World 中为人创建一个身体。
const [mesh, api] = useSphere(() => ({
    mass: 10,
    position: [0, 1, 0],
    type: 'Dynamic',
}))
  1. 将速度应用于球体。
useFrame(() => {
    // Calculating front/side movement ...
    frontVector.set(0, 0, Number(forward) - Number(backward))
    sideVector.set(Number(right) - Number(left), 0, 0)
    direction
      .subVectors(frontVector, sideVector)
      .normalize()
      .multiplyScalar(SPEED)

    api.velocity.set(direction.x, 0, direction.z)
})
  1. 现在我们的球体能够随着用户在 Cannon World 中的输入而移动,所以现在只需使用球体在每一帧上的位置更新您的玩家模型,就像这样
// Setting person model position to sphere body position ...
useFrame(() => {
    ...
    mesh.current.getWorldPosition(playerModelReference.current.position)
})

抱歉解释太长了,希望对您有所帮助。


推荐阅读