ThreeJS导出GLTF/GLB时场景层级结构被破坏的问题
解决Three.js GLTF导出层级结构被破坏的问题
我使用以下代码导出Three.js场景:
function save(blob, filename) { const link = document.createElement("a"); link.href = URL.createObjectURL(blob); link.download = filename; link.click(); URL.revokeObjectURL(link); } function saveString(text, filename) { save(new Blob([text], { type: "text/plain" }), filename); } function saveArrayBuffer(buffer, filename) { save(new Blob([buffer], { type: "application/octet-stream" }), filename); } const exporter = new GLTFExporter(); exporter.parse( scene, function (result) { const name = `${modelName}.glb`; if (result instanceof ArrayBuffer) { saveArrayBuffer(result, name); } else { const output = JSON.stringify(result, null, 2); saveString(output, name); } }, function (error) { console.log(error); }, { binary: true, animations: [mixer.clipAction(model.animations[0]).getClip()], } );
但导出后场景层级结构被破坏:原本直接挂载在scene下的对象,被自动嵌套到一个新创建的空对象中。我需要导出时保留场景的原始层级结构,同时保留对象的动画。
导出前场景层级:
导出后场景层级:
解决方法
GLTFExporter默认导出整个Scene对象时,会自动创建一个根包裹节点,导致层级嵌套。要保留原始层级,只需将导出目标从scene改为scene.children(场景的子节点数组),让原直接挂载在scene下的对象成为GLB的根层级对象。
修改后的导出代码:
function save(blob, filename) { const link = document.createElement("a"); link.href = URL.createObjectURL(blob); link.download = filename; link.click(); URL.revokeObjectURL(link); } function saveString(text, filename) { save(new Blob([text], { type: "text/plain" }), filename); } function saveArrayBuffer(buffer, filename) { save(new Blob([buffer], { type: "application/octet-stream" }), filename); } const exporter = new GLTFExporter(); exporter.parse( scene.children, // 直接导出场景子节点数组,避免自动创建根包裹对象 function (result) { const name = `${modelName}.glb`; if (result instanceof ArrayBuffer) { saveArrayBuffer(result, name); } else { const output = JSON.stringify(result, null, 2); saveString(output, name); } }, function (error) { console.error(error); }, { binary: true, animations: [mixer.clipAction(model.animations[0]).getClip()], } );
注意事项
- 确保需要导出的动画目标对象存在于
scene.children数组中,避免动画丢失或路径错误。 - 如果动画引用出现异常,可以尝试使用
THREE.AnimationUtils.stringifyClip()处理动画剪辑,或确保场景中对象名称唯一,避免路径解析冲突。
内容的提问来源于stack exchange,提问作者Mustafa AHCI
相关产品推荐
相关产品推荐

