react-three-fiber - 反应三纤维如何控制人的运动?
问题描述
我想创建一个游戏,我必须通过键盘输入使我的模型可控。我不知道最好的方法是什么以及如何正确实施。
解决方案
我们可以用 cannon.js 来实现它
- 创建一个自定义挂钩来监听用户的输入。
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()
- 在 Cannon World 中为人创建一个身体。
const [mesh, api] = useSphere(() => ({
mass: 10,
position: [0, 1, 0],
type: 'Dynamic',
}))
- 将速度应用于球体。
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)
})
- 现在我们的球体能够随着用户在 Cannon World 中的输入而移动,所以现在只需使用球体在每一帧上的位置更新您的玩家模型,就像这样
// Setting person model position to sphere body position ...
useFrame(() => {
...
mesh.current.getWorldPosition(playerModelReference.current.position)
})
抱歉解释太长了,希望对您有所帮助。
推荐阅读
- android - 我如何从普通的 java 类中为 Activity 类调用 Intent 的 startActivty()?
- java - 需要在哈希图中找到对象类型值的键
- qt - 自定义 TableViewColumn 委托问题
- android - 活动/服务和小部件提供者之间的通信?
- android - 如何在 HorizontalCoordinatorNtbActivity 中为书签设置不同的文本
- node.js - Angular 应用程序 fs.readFileSync 替代方案
- node.js - NodeJS - config 不加载配置文件
- javascript - 在反应中使用 datatables.net 格式化日期
- python - 访问元素列表并在 HTML 中打印出来
- css - 如何使用 Angular 5 在 SPA 中使用多个主题