THREE.js v0.86结合React:如何让相机看向特定子对象
Hey there! Let's work through getting your desired functionality working—targeting a child object, updating its material color, and making the camera lock onto it properly, whether TrackballControls are enabled or not.
Step 1: Correctly Get the Child's World Position
First, remember that a child object's position property is local to its parent. To get its actual world space position, use getWorldPosition() in THREE.js v0.86. You'll need to pass a THREE.Vector3 to store the result:
const worldPos = new THREE.Vector3(); yourChildObject.getWorldPosition(worldPos);
Pro tip: If the parent/child has just been moved or added to the scene, call yourChildObject.updateMatrixWorld(true) first to ensure the matrix is up-to-date before fetching the world position.
Step 2: Update the Child's Material Color
This part is straightforward, but keep an eye out for shared materials. If multiple objects use the same material, changing it will affect all of them. Here's how to handle both cases:
// Case 1: Unique material (safe to modify directly) yourChildObject.material.color.set(0xff0000); // Red, change to your desired hex // Case 2: Shared material (clone first to only affect this child) yourChildObject.material = yourChildObject.material.clone(); yourChildObject.material.color.set(0x00ff00); // Green
Step 3: Make the Camera Look at the Child (With/Without TrackballControls)
This is where things often go wrong—TrackballControls overrides the camera's lookAt unless you update its target. Let's cover both scenarios:
When TrackballControls is Enabled
Instead of calling camera.lookAt(), update the controls' target and trigger an update:
// Assume you have references to your controls and camera stored in your component controls.target.copy(worldPos); controls.update(); // Critical—tells the controls to apply the new target
When TrackballControls is Disabled
You can directly use the camera's lookAt method:
camera.lookAt(worldPos);
Putting It All Together in Your moveCamera Function
Here's a complete example tailored to your React + THREE.js setup, assuming you've stored child object references in your component (like in onLoad):
// Inside your React component moveCamera = (childName) => { const targetChild = this.storedChildObjects[childName]; if (!targetChild) return; // Exit if child doesn't exist // Get world position const worldPosition = new THREE.Vector3(); targetChild.updateMatrixWorld(true); // Ensure matrix is fresh targetChild.getWorldPosition(worldPosition); // Update material color targetChild.material = targetChild.material.clone(); // Avoid shared material issues targetChild.material.color.set(0x0000ff); // Blue, adjust as needed // Handle camera/controls logic const { camera, controls } = this; if (controls.enabled) { controls.target.copy(worldPosition); controls.update(); } else { camera.lookAt(worldPosition); } // Trigger a re-render (React + THREE.js) this.forceUpdate(); // Or call your custom renderScene() function }
Quick Troubleshooting Tips
- Double-check that
storedChildObjectsactually holds valid references to your child meshes (no undefined values). - If the camera isn't moving, ensure your render loop is running and picking up the camera/controls changes.
- For THREE.js v0.86, confirm
TrackballControlsis set up correctly—older versions might require explicitupdate()calls after target changes.
内容的提问来源于stack exchange,提问作者LuisEgan

