How to make the camera follow a moving target without breaking OrbitControls?

Hi everyone,

I’m working on a Three.js demo and ran into an issue with camera control. I would appreciate any advice from the community.

Scene description:

  • I have a moving target object (e.g., a box moving on a grid).

  • I want the camera to follow this target while keeping the functionality of OrbitControls (rotation and zoom).

  • The camera has an initial offset relative to the target, and I want to maintain this offset while following.

  • Users should still be able to rotate and zoom freely with OrbitControls without breaking the follow behavior.

  • Ideally, there should be a “reset” function that restores the camera to its initial offset relative to the target while continuing to follow.

Problem:
I tried updating the camera every frame like this:

camera.position.copy(target.position).add(offset);
controls.target.copy(target.position);
controls.update();

However, this resets the OrbitControls rotation center every frame, which makes the controls feel unnatural.

Questions:

  1. What is the best way to make the camera smoothly follow a target while preserving OrbitControls rotation and zoom?

  2. How can the camera maintain the current offset relative to the target even when the user rotates the scene with OrbitControls?

  3. How can I implement a “reset” function that restores the initial offset and continues following without snapping or losing the current rotation state?

Thank you for your suggestions!

https://codesandbox.io/p/sandbox/wkjz6s

You mean something beyond:

controls.target.copy( thePointYouWantToLookAt ) ?

What I’m trying to achieve is closer to a third-person game camera.
The target object is moving, and I want the camera to follow that movement with a fixed offset, while still allowing the user to freely rotate the view using OrbitControls.

So it’s not just about updating controls.target.copy(...).
I tried that, but since the target moves every frame, OrbitControls keeps having its rotation center overridden, which makes the camera interaction feel unnatural — the view snaps or shifts instead of keeping the user’s current orientation.

In other words, I’m looking for a setup where:

  • the camera rig follows the moving target,

  • the user can still orbit and zoom naturally,

  • and both behaviors do not interfere with each other — similar to how you can move a character and freely adjust the camera in a typical 3D game.

1 Like

Track a character, aiming at 1 unit above it’s origin. (Hopefully roughly head height :slight_smile: )

camera.position.sub(controls.target);
character.localToWorld(controls.target.set(0,1,0));
camera.position.add(controls.target);

If you need to track at some fixed offset in camera space..

let camSpaceOffset= new THREE.Vector3();
...
camera.position.sub(controls.target);
character.localToWorld(controls.target.set(0,1,0)); //Character space offset
camSpaceOffset.set(1,0,0).applyQuaternion(camera.quaternion);
controls.target.add( camSpaceOffset ); // Camera space offset
camera.position.add(controls.target);

Keep camera+controls locked on moving/rotating player:

character.worldToLocal(controls.target);
character.worldToLocal(camera.position);


UPDATE_YOUR_CHARACTER_HERE() // Rotate / move your character here..
//This can be the character itself, or for instance, the characters head bone...
//In which case, you would call your animationMixer.update() here as well to update the bone..

character.updateMatrixWorld(true); //Make sure its matrices are up to date.. (may not be neccesary)
character.localToWorld(controls.target);
character.localToWorld(camera.position)

(these operations should be done right before you call “controls.update()” in your render loop)

3 Likes

If the character has an initial rotation, how do you compute the camera offset so that the camera always stays at the character’s true back? I’ve made a small demo here: https://codesandbox.io/p/sandbox/wkjz6s
Could you help implement this behavior in the demo?

The codesandbox is 404, but I added a section ^ for locking on moving/rotating character.

Sorry, it was private before~

https://codesandbox.io/p/sandbox/wkjz6s