简体   繁体   English

无法将指针锁与 PerspectiveCamera 和 PointerLockControls 一起使用

[英]Unable to use Pointer Lock with PerspectiveCamera and PointerLockControls

I like react-three and I am trying to make an FPV character with a body: https://codesandbox.io/s/fpv-player-ers63 So the goal is that the camera is placed at the head level and the character moves around like in original example https://codesandbox.io/s/minecraft-vkgi6 by Paul Henschel drcmda我喜欢 react-three,我正在尝试用身体制作一个 FPV 角色: https://codesandbox.io/s/fpv-player-ers63所以目标是将相机放置在头部水平并且角色移动就像 Paul Henschel drcmda 的原始示例https: //codesandbox.io/s/minecraft-vkgi6

I have added PerspectiveCamera to change the camera position but now PointerLockControls doesn't work any more and I do not understand why and how to handle it.我添加了 PerspectiveCamera 来更改相机 position 但现在 PointerLockControls 不再起作用,我不明白为什么以及如何处理它。

Thank you谢谢

PerspectiveCamera usage透视相机使用

export const Player = (props) => {
  const axe = useRef()
  const [ref, api] = useSphere(() => ({ mass: 1, type: "Dynamic", position: [0, 10, 0], ...props }))
  const { forward, backward, left, right, jump } = usePlayerControls()
  const { camera } = useThree()
  const velocity = useRef([0, 0, 0])
  useEffect(() => api.velocity.subscribe((v) => (velocity.current = v)), [])
  useFrame((state) => {
    ref.current.getWorldPosition(camera.position)
    frontVector.set(0, 0, Number(backward) - Number(forward))
    sideVector.set(Number(left) - Number(right), 0, 0)
    direction.subVectors(frontVector, sideVector).normalize().multiplyScalar(SPEED).applyEuler(camera.rotation)
    speed.fromArray(velocity.current)
    axe.current.children[0].rotation.x = THREE.MathUtils.lerp(
      axe.current.children[0].rotation.x,
      Math.sin((speed.length() > 1) * state.clock.elapsedTime * 10) / 20,
      0.01,
    )
    axe.current.rotation.copy(camera.rotation)
    axe.current.position.copy(camera.position).add(camera.getWorldDirection(rotation).multiplyScalar(1))

    api.velocity.set(direction.x, velocity.current[1], direction.z)
    if (jump && Math.abs(velocity.current[1].toFixed(2)) < 0.05) api.velocity.set(velocity.current[0], 10, velocity.current[2])
  })
  return (
    <>
      <mesh ref={ref} />
      <group ref={axe} onPointerMissed={(e) => (axe.current.children[0].rotation.x = -0.5)}>
        <group position={[0, 7, 0]}>
          <PerspectiveCamera makeDefault={true} fov={75}>
            <Body position={[0, -4, 1]} />
          </PerspectiveCamera>
        </group>
      </group>
    </>
  )
}

PointerLockControls usage PointerLockControls 用法

export default function App() {
  return (
    <Canvas
      shadows
      gl={{ alpha: false }}
      camera={{ fov: 45 }}
      raycaster={{
        computeOffsets: (e) => ({ offsetX: e.target.width / 2, offsetY: e.target.height / 2 }),
      }}>
      <Sky sunPosition={[100, 20, 100]} />
      <ambientLight intensity={0.3} />
      <pointLight castShadow intensity={0.8} position={[100, 100, 100]} />
      <Physics gravity={[0, -30, 0]}>
        <Ground />
        <Player />
        <Reflector
          blur={[0, 0]} // Blur ground reflections (width, heigt), 0 skips blur
          mixBlur={0.1} // How much blur mixes with surface roughness
          mixStrength={0.25} // Strength of the reflections
          resolution={1024} // Off-buffer resolution, lower=faster, higher=better quality
          args={[10, 30]} // PlaneBufferGeometry arguments
          position={[0, 0, -20]}
          rotation={[0, 0, 2 * Math.PI]}
          mirror={0.5} // Mirror environment, 0 = texture colors, 1 = pick up env colors
          minDepthThreshold={0.25}
          maxDepthThreshold={1}
          depthScale={50}>
          {(Material, props) => <Material metalness={0} roughness={0} {...props} />}
        </Reflector>
      </Physics>
      <PointerLockControls />
    </Canvas>
  )
}

Browser: Firefox 94.0.2 (64-bit), macOS Monterey浏览器:Firefox 94.0.2(64 位),macOS Monterey

"dependencies": { "@pmndrs/branding": "0.0.8", "@react-three/cannon": "4.0.1", "@react-three/drei": "7.17.2", "@react-three/fiber": "7.0.17", "@types/three": "0.133.1", "react": "17.0.2", "react-dom": "17.0.2", "react-scripts": "4.0.3", "simplex-noise": "3.0.0", "three": "0.133.1", "zustand": "3.6.1" }, “依赖”:{“@pmndrs/branding”:“0.0.8”,“@react-three/cannon”:“4.0.1”,“@react-three/drei”:“7.17.2”,“@ react-three/fiber": "7.0.17", "@types/three": "0.133.1", "react": "17.0.2", "react-dom": "17.0.2", "react -scripts”:“4.0.3”,“simplex-noise”:“3.0.0”,“三个”:“0.133.1”,“zustand”:“3.6.1”},

https://codesandbox.io/s/fpv-player-ers63 https://codesandbox.io/s/fpv-player-ers63

Well, I found that it is sufficient to offset the camera in useFrame update https://codesandbox.io/s/fpv-player-ers63好吧,我发现在useFrame update https://codesandbox.io/s/fpv-player-ers63中偏移相机就足够了

export const Player = (props) => {
  const axe = useRef()
  const [ref, api] = useSphere(() => ({ args: [1], mass: 1, type: "Dynamic", position: [0, 10, 0], ...props }))
  const { forward, backward, left, right, jump } = usePlayerControls()
  const { camera } = useThree()
  const velocity = useRef([0, 0, 0])
  useEffect(() => api.velocity.subscribe((v) => (velocity.current = v)), [])
  useFrame((state) => {
    ref.current.getWorldPosition(camera.position)
    frontVector.set(0, 0, Number(backward) - Number(forward))
    sideVector.set(Number(left) - Number(right), 0, 0)
    direction.subVectors(frontVector, sideVector).normalize().multiplyScalar(SPEED).applyEuler(camera.rotation)
    speed.fromArray(velocity.current)
    axe.current.children[0].rotation.x = THREE.MathUtils.lerp(
      axe.current.children[0].rotation.x,
      Math.sin((speed.length() > 1) * state.clock.elapsedTime * 10) / 10,
      0.1,
    )
    axe.current.rotation.copy(camera.rotation)
    axe.current.position.copy(camera.position).add(camera.getWorldDirection(rotation).multiplyScalar(1))
    camera.position.setY(camera.position.y + 8)
    api.velocity.set(direction.x, velocity.current[1], direction.z)
    if (jump && Math.abs(velocity.current[1].toFixed(2)) < 0.05) api.velocity.set(velocity.current[0], 10, velocity.current[2])
  })
  return (
    <>
      <mesh ref={ref} />
      <group ref={axe} onPointerMissed={(e) => (axe.current.children[0].rotation.x = -0.5)}>
        <Body position={[0, 4, 0]} />
      </group>
    </>
  )
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM