You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 19:26:12