使用Drei PivotControls拖动后,如何获取Mesh的更新位置?
解决Drei PivotControls拖动后获取Mesh位置的问题
问题原因
你遇到位置始终显示[0,0,0]的核心原因有两个:
- 你的
<primitive>组件通过position={position}绑定了受控状态值,React Three Fiber会在每次渲染时将Mesh位置重置为该状态值,覆盖PivotControls的修改; - 你直接访问的是
<primitive>组件引用,而Mesh的实际位置存储在其内部的3D对象上,而非组件本身。
修复方案
1. 移除受控position绑定(非必要场景)
如果不需要通过state控制Mesh位置,先去掉<primitive>上的position={position},让PivotControls直接操控Mesh的transform:
const meshRef = useRef(); const handleDragEnd = () => { const model = meshRef.current; // 获取本地位置(相对于父对象的坐标) const localPos = model.object.position; console.log('本地位置:', `${localPos.x}, ${localPos.y}, ${localPos.z}`); // 若需要世界位置,先更新矩阵再获取 const worldPos = new THREE.Vector3(); model.object.getWorldPosition(worldPos); console.log('世界位置:', `${worldPos.x}, ${worldPos.y}, ${worldPos.z}`); }; return ( <PivotControls anchor={[0, 0, 0]} onDragEnd={handleDragEnd}> <primitive ref={meshRef} scale={scale} rotation={rotation} object={loadedModel.scene} /> </PivotControls> )
2. 同步受控state(需state管理位置场景)
如果必须用state管理位置,需要在onDragEnd事件中同步更新state,避免渲染时的位置重置:
const [position, setPosition] = useState([0, 0, 0]); const meshRef = useRef(); const handleDragEnd = () => { const obj = meshRef.current.object; // 将PivotControls修改的位置同步到state setPosition([obj.position.x, obj.position.y, obj.position.z]); console.log('更新后的位置:', obj.position); }; return ( <PivotControls anchor={[0, 0, 0]} onDragEnd={handleDragEnd}> <primitive ref={meshRef} scale={scale} position={position} rotation={rotation} object={loadedModel.scene} /> </PivotControls> )
关键说明
<primitive>的ref指向组件实例,内部的3D对象需通过.object属性访问;- 调用
getWorldPosition()获取世界位置前,确保对象的矩阵已更新(默认拖动后会自动更新); - 使用受控state时,必须同步PivotControls的修改到state,否则R3F的渲染逻辑会重置Mesh位置。
内容的提问来源于stack exchange,提问作者Ashbury
相关产品推荐
相关产品推荐

