如何解决Three.js中crossFadeTo()切换动画时角色回到T姿的问题
Mixamo动画切换时角色回到T姿的解决方案
核心问题分析
crossFadeTo参数误用:第三个reset参数设为true会强制目标动画重置到初始状态(也就是Mixamo动画的T姿基准态),这是切换时跳回T姿的直接原因。- 重复创建AnimationAction:每次切换时调用
mixer.clipAction生成新Action,没有复用已创建的实例,导致动画状态管理混乱。 - 未更新当前Action引用:切换后没把
this.action更新为新动画的Action,后续操作会基于旧Action重复执行过渡,引发冲突。
修复步骤
- 提前预创建所有AnimationAction:在加载完成后一次性生成所有动画对应的Action并存储,避免每次切换重复创建。
- 调整
crossFadeTo参数:将第三个reset参数改为false,让目标动画从角色当前骨骼状态平滑过渡,而非重置到T姿。 - 切换后更新当前Action引用:完成过渡后将当前Action替换为新的,确保后续操作基于正确的动画实例。
- 优化事件监听:如果动画非循环,建议监听
finished事件而非loop,确保触发时机准确。
修改后的代码
loadAnimations(){ const loader = new FBXLoader(); var that = this; for(var i=0;i<this.animationFiles.length;i++){ loader.load(that.animationFiles[i], function(animObj){ that.animations.push(animObj.animations[0]); }, function(){ console.log(Math.round(100*((that.animations.length+1)/that.animationFiles.length))+'% loaded'); if((that.animations.length+1)==that.animationFiles.length) { that.finishedLoading(); } } ); } } finishedLoading(){ console.log(this.animations); this.mixer = new THREE.AnimationMixer(this.tpose); // 预创建所有动画的Action并存在Map里 this.actionMap = new Map(); this.animations.forEach((clip, index) => { const action = this.mixer.clipAction(clip); action.setEffectiveTimeScale(1); action.setEffectiveWeight(1); this.actionMap.set(index, action); }); // 初始化播放指定动画 this.currentAction = this.actionMap.get(1); this.currentAction.play(); // 非循环动画用finished监听,循环动画改回loop即可 this.mixer.addEventListener('finished', this.animationEnd.bind(this)); } animationEnd(){ console.log('animation end'); var randomIndex = Math.floor(Math.random()*this.animations.length); console.log('playing animation#'+randomIndex); const nextAction = this.actionMap.get(randomIndex); // 避免重复切换到当前正在播放的动画 if(nextAction === this.currentAction) return; // 平滑过渡,关闭reset避免回到T姿 this.currentAction.crossFadeTo(nextAction, 1, false); // 更新当前Action引用 this.currentAction = nextAction; // 确保新动画处于播放状态 this.currentAction.play(); }
补充说明
- 预创建
actionMap可以复用Action实例,避免每次创建新实例带来的状态重置问题。 - 关闭
reset参数后,目标动画会基于角色当前的骨骼位置开始过渡,完全避免T姿跳转。 - 增加的重复动画判断可以防止无意义的过渡操作,优化性能。
内容的提问来源于stack exchange,提问作者iPadDeveloper2011
相关产品推荐
相关产品推荐

