ThreeJs问题:已带动画模型旋转后坐标重置,如何实现相对旋转?
可行,提供三种解决方案:
1. 层级分离动画与控制旋转
- 给飞船模型套一个空的
Object3D父容器,将随机摆动动画仅绑定到飞船子对象上。 - 用户按键控制时,只修改父容器的旋转属性。这样飞船的局部摆动动画会基于父容器的旋转轴运行,实现“围绕新轴摆动”的效果,且动画不会覆盖用户设置的整体旋转。
2. 让动画基于局部坐标系播放
- 调整ThreeJS中动画动作的设置,确保动画更新的是模型的局部旋转,而非覆盖整体旋转:
// 假设shipAction是飞船的动画动作 shipAction.setLoop(THREE.LoopRepeat); shipAction.clampWhenFinished = false; // 确保动画以局部坐标系叠加 shipAction.setEffectiveWeight(1); - 处理键盘事件时直接修改模型的
localRotation:document.addEventListener('keydown', (e) => { const rotateStep = Math.PI / 180 * 30; // 30度弧度值 if (e.key === 'ArrowLeft') { shipMesh.localRotation.y += rotateStep; } else if (e.key === 'ArrowRight') { shipMesh.localRotation.y -= rotateStep; } });
3. 手动叠加动画与控制旋转
- 如果前两种方法不适用,可在每一帧手动合并用户控制的旋转和动画的摆动偏移:
let userRotateY = 0; const clock = new THREE.Clock(); // 监听键盘事件记录用户旋转量 document.addEventListener('keydown', (e) => { const step = Math.PI / 180 * 30; if (e.key === 'ArrowLeft') userRotateY += step; else if (e.key === 'ArrowRight') userRotateY -= step; }); // 动画循环中叠加旋转 function animate() { requestAnimationFrame(animate); const delta = clock.getDelta(); // 先更新动画 mixer,获取当前帧的摆动旋转 mixer.update(delta); const animRotate = shipMesh.rotation.clone(); // 重置模型旋转,叠加用户控制量和动画摆动 shipMesh.rotation.set(0, userRotateY, 0); shipMesh.rotateX(animRotate.x); shipMesh.rotateZ(animRotate.z); } animate();
内容的提问来源于stack exchange,提问作者A B
相关产品推荐
相关产品推荐

