
Three.js 报错 “No target node found for track” 通常是因为动画轨道(如 LowerBone.position)指向的骨骼节点在模型场景树中不存在,根本原因是误将 gltf.asset 赋值给动画目标对象,而正确目标应为 gltf.scene 或其子对象(如 gltf.nodes['LowerBone'])。
three.js 报错 “no target node found for track” 通常是因为动画轨道(如 `lowerbone.position`)指向的骨骼节点在模型场景树中不存在,根本原因是误将 `gltf.asset` 赋值给动画目标对象,而正确目标应为 `gltf.scene` 或其子对象(如 `gltf.nodes['lowerbone']`)。
在 Three.js 中使用 GLTF 模型进行骨骼动画时,AnimationMixer 和 clipAction 必须绑定到包含所有骨骼节点的实际场景对象上。而 gltf.asset 并非标准 GLTFLoader 加载结果中的有效属性——它根本不存在于 GLTF 实例中,属于典型误读或调试残留导致的错误赋值。
? 错误根源分析
原代码中关键错误行如下:
model = gltf.asset; // ❌ 错误!gltf 没有 .asset 属性 mixer = new THREE.AnimationMixer(model); intro = mixer.clipAction(gltf.animations[2], model); // 目标 model 为空/无效 → 所有骨骼路径解析失败
GLTFLoader 返回的 gltf 对象结构为:
- gltf.scene: 已实例化的完整场景图(含 mesh、bones、group 等,这是动画的目标容器)
- gltf.nodes: 按名称索引的节点数组(可用于精确查找骨骼)
- gltf.animations: 动画剪辑数组(每个 clip 的 tracks 依赖 nodeNames 与实际节点匹配)
- gltf.asset: 不存在的属性(开发者误以为类似 JSON 中的 "asset" 字段,实则 loader 不暴露该字段)
当 model = gltf.asset 时,model 变为 undefined,AnimationMixer 初始化虽不报错,但后续 clipAction(..., model) 无法定位任何骨骼节点(如 LowerBone),于是逐个抛出 No target node found for track: LowerBone.position 等警告,动画完全失效。
✅ 正确写法(修复后核心逻辑)
loader.load('untitled.gltf', (gltf) => {
// ✅ 正确:使用 gltf.scene 作为动画目标
const modelScene = gltf.scene;
scene.add(modelScene);
console.log('Loaded animations:', gltf.animations);
console.log('Available nodes:', Object.keys(gltf.nodes)); // 可用于验证骨骼名是否存在
// 创建 mixer 并绑定到 gltf.scene
const mixer = new THREE.AnimationMixer(modelScene);
// ✅ 正确:clipAction 第二个参数必须是包含目标节点的 object3D(通常是 gltf.scene)
const introAction = mixer.clipAction(gltf.animations[2], modelScene);
introAction.setLoop(THREE.LoopRepeat);
introAction.play();
// 若需单独控制某骨骼,可显式传入节点(非必需,scene 已足够)
// const lowerBone = gltf.nodes['LowerBone'];
// const boneAction = mixer.clipAction(gltf.animations[0], lowerBone);
// ⚠️ 注意:一个 mixer 足以驱动整个 scene,无需为同一模型创建多个 mixer
// 删除 mixer1/mixer2/mixer3 —— 多 mixer 会竞争更新且浪费性能
});? 关键注意事项
- 不要创建多个 AnimationMixer 实例作用于同一模型:每个 AnimationMixer 都需独立 update(delta),多 mixer 易导致状态冲突、性能下降及逻辑混乱。单个 mixer 即可管理全部动画。
- 验证骨骼名称是否匹配:GLTF 中骨骼名区分大小写,且可能被 Blender 导出插件重命名(如添加 .001 后缀)。可通过 console.log(gltf.nodes) 确认真实名称。
- 确保模型已加入场景再初始化 mixer:mixer 依赖场景图遍历节点,scene.add(gltf.scene) 必须在 new AnimationMixer() 之前完成。
- 启用骨骼网格支持(如适用):若使用 SkinnedMesh,确保材质启用 skinning: true,且模型已正确绑定蒙皮。
? 调试技巧
遇到类似问题,建议按以下最小化步骤排查:
- 仅加载模型 + 打印 gltf.scene.children 和 gltf.nodes
- 创建单一 mixer + 播放第一个动画
- 逐步添加交互逻辑,避免“一次加太多”导致关键链路断裂(正如提问者所反思)
遵循官方文档中 AnimationMixer 和 GLTFLoader 的用例,可大幅降低此类配置类错误发生概率。


















