ChirAdi
ChirAdi

Reputation: 43

React Three- Code a 3rd person view camera

I'm trying to set dynamic camera position behind the car implemented in a project similar to CAR using raycastVehicle

I tried to change camera's position using state/hooks, but I am unable locate car's position as useRaycastVehicle is used.

You can look at the similar code of car model at https://codesandbox.io/s/ebr0x . I'm trying to set a moving camera behind the car. Thanks for your help.

part of code handling car's physics,etc

function Vehicle({ radius = 0.7, width = 1.2, height = -0.04, front = 1.3, back = -1.15, steer = 0.75, force = 2000, maxBrake = 1e5, ...props }) {
  const chassis = useRef()
  const wheel1 = useRef()
  const wheel2 = useRef()
  const wheel3 = useRef()
  const wheel4 = useRef()
  const controls = useControls()
..............................................
 useFrame(() => {
    const { forward, backward, left, right, brake, reset } = controls.current
    for (let e = 2; e < 4; e++) api.applyEngineForce(forward || backward ? force * (forward && !backward ? -1 : 1) : 0, 2)
    for (let s = 0; s < 2; s++) api.setSteeringValue(left || right ? steer * (left && !right ? 1 : -1) : 0, s)
    for (let b = 2; b < 4; b++) api.setBrake(brake ? maxBrake : 0, b)
    if (reset) {
      chassis.current.api.position.set(0, 0.5, 0)
      chassis.current.api.velocity.set(0, 0, 0)
      chassis.current.api.angularVelocity.set(0, 0.5, 0)
      chassis.current.api.rotation.set(0, -Math.PI / 4, 0)
    }
  })

  return (
    <group ref={vehicle} position={[0, -0.4, 0]}>
      <Beetle ref={chassis} rotation={props.rotation} position={props.position} angularVelocity={props.angularVelocity} />
      <Wheel ref={wheel1} radius={radius} leftSide />
      <Wheel ref={wheel2} radius={radius} />
      <Wheel ref={wheel3} radius={radius} leftSide />
      <Wheel ref={wheel4} radius={radius} />
    </group>

Upvotes: 0

Views: 1971

Answers (1)

WillMaddicott
WillMaddicott

Reputation: 532

So I had to do something similar the other day. You'll need to put the camera in with a group with the model itself,

     <group ref={targetRef}>
        <PerspectiveCamera
          makeDefault
          position={[25, 22, 25]}
          args={[45, 1.2, 1, 1000]}
        />
        <mesh castShadow receiveShadow position={[0, 2, 0]}>
          <boxBufferGeometry args={[2, 2, 2]} />
          <meshStandardMaterial color={"#ff0000"} />
        </mesh>
     </group>

and then animate the group ref in useFrame

  useFrame((state, delta) => {
    targetRef.current.position.x += moveRight ? 0.2 : moveLeft ? -0.2 : 0;
    targetRef.current.position.z += moveForward
      ? -0.2
      : moveBackward
      ? +0.2
      : 0;
    state.camera.lookAt(targetRef.current.position);
    state.camera.updateProjectionMatrix();
  });

I've put together a very brief example here https://codesandbox.io/s/distracted-wozniak-yvfrn4?file=/src/App.js

Control Keys are AWSD and you may need to run it in full screen to see it work

EDIT TO ADD

So I've been having a play around and have managed to get a better third person camera with a more natural movement. It follows the target but is essentially on a trolly following the target vehicle

Here https://codesandbox.io/s/recursing-morning-jqerty?file=/src/Scene.js

Further Edit

I've got an example of the above working with a React Three Fiber Cannon Raycast Vehicle, Should be easy enough to use as a template

here https://codesandbox.io/s/angry-cache-oxdh0x

Low Poly car driving around some trees

Upvotes: 1

Related Questions