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

在Three.js中使用Tween.js实现GLTF模型三轴同步旋转的问题

解决TWEEN.js同时驱动Three.js模型三轴旋转的问题

核心问题在于Three.js的Euler对象(也就是theObject.rotation)的x/y/z是getter/setter属性,不是普通的可写变量,而TWEEN.js默认只能对普通JS对象的基础属性做插值。另外你直接访问_x/_y/_z是踩了私有变量的坑——这些是Three.js内部维护的字段,不应该直接读写。

给你两个可行的方案,都能实现单语句式的三轴旋转动画,且不需要为每个轴单独写逻辑:

方案一:用中间对象配合单次onUpdate(最实用)

先创建一个普通的JS对象存初始角度,让TWEEN做插值,然后在onUpdate里一次性把插值结果赋值给模型的rotation:

// 计算目标角度,用Three.js官方的角度转换工具,不要自己写degreeToRadian
const target = {
  x: theObject.rotation.x + THREE.MathUtils.degToRad(-120),
  y: theObject.rotation.y + THREE.MathUtils.degToRad(10),
  z: theObject.rotation.z + THREE.MathUtils.degToRad(30)
};

new TWEEN.Tween({ 
  x: theObject.rotation.x, 
  y: theObject.rotation.y, 
  z: theObject.rotation.z 
})
  .to(target, 3000)
  .delay(2000)
  .easing(TWEEN.Easing.Quadratic.InOut)
  .onUpdate(function() {
    // 用Euler的set方法一次性赋值,触发Three.js的属性更新
    theObject.rotation.set(this.x, this.y, this.z);
  })
  .start();

这个方案只需要一个onUpdate,而且逻辑集中,完全不需要拆分轴处理。

为什么你之前的代码无效?

  1. 直接TweentheObject.rotation:TWEEN无法正确识别Euler的getter/setter属性,插值过程中不会触发Three.js的属性更新逻辑,所以模型不会动。
  2. 传new THREE.Euler()给.to():TWEEN的.to()需要接收普通键值对对象,不是Three.js的Euler实例,它没法对Euler对象做插值计算。
  3. 访问_x/_y/_z:这些是内部私有变量,Three.js可能随时修改它们的命名或逻辑,绝对不要直接依赖。

内容的提问来源于stack exchange,提问作者user3532287

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 00:10:11