Camera-Controls => Loading and functional control

I have an issue with camera controls. I feel it should be easy but can’t find a way. I’d like the camera to be disabled from any user input. like the user can not move it manually, neither pan, nor rotate, etc… I want camera movement to be functional and triggered by pressing a button or something else but the user can not freely move.

I am using Camera Controls from drei because it has very nice and fluid movement effects but somehow I can not manage to do 2 things properly:

  1. disable user input. I have tried enabled = false, disconnect, etc… I can always still move my camera with my mouse
  2. setting up a default lookAt without using a timeout inside a useEffectLayout because somehow it’s triggering it before everything is loaded I guess but my camera always points at 0,0,0 if I don’t add a setTimeout which is ugly and unreliable. (actually even with setTimeout doesn’t work most of the time)

That’s my code now:

  useLayoutEffect(() => {
    const controls = cameraControlRef.current;
    if (!controls) return;

    setTimeout(() => {
      goToClient();
      controls.enabled = false;
      // controls.disconnect()
    }, 3000);
  }, [cameraControlRef.current]);

  const goToClient = () => {
    const camera = cameraControlRef.current;
    if (!camera) return;
    camera.rotate(Math.PI / 4, 0, true);
  };

  return (
    <>
      <directionalLight position={[-10, 40, 40]} intensity={5} castShadow />
      <ambientLight intensity={0.6} />
      <CameraControls ref={cameraControlRef} />
      <axesHelper args={[20]} />
      <Center>
        <primitive object={scene} />
      </Center>
      <PerspectiveCamera
        makeDefault
        position={[-30, 30, 30]} // x, y, z coordinates
      />
    </>
  );
};

Something I am still unsure is the need to add the controls.update() in the useFrame (is it necessary ?)

With or without I get similar results.

to disable user input things, use the mouseButtons / touches props

<CameraControls
 mouseButtons={{ left: 0, middle: 0, right: 0, wheel: 0 }}
 touches={{ one: 0, three: 0, two: 0 }} />

then maybe use a setLookAt or similar method

  useEffect(() => {
    if (!camRef.current) return
      camRef.current.setLookAt(positionX, positionY, positionZ, targetX, targetY, targetZ, enableTransition)
  }, [camRef])

no need to manually update these controls inside useFrame

1 Like