在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,而且逻辑集中,完全不需要拆分轴处理。
为什么你之前的代码无效?
- 直接Tween
theObject.rotation:TWEEN无法正确识别Euler的getter/setter属性,插值过程中不会触发Three.js的属性更新逻辑,所以模型不会动。 - 传
new THREE.Euler()给.to():TWEEN的.to()需要接收普通键值对对象,不是Three.js的Euler实例,它没法对Euler对象做插值计算。 - 访问
_x/_y/_z:这些是内部私有变量,Three.js可能随时修改它们的命名或逻辑,绝对不要直接依赖。
内容的提问来源于stack exchange,提问作者user3532287
相关产品推荐
相关产品推荐

