ThreeJS:异步加载FBX对象后如何在外部访问其属性?
解决FBX加载后外部访问对象属性的问题
方法1:在外层作用域声明变量存储对象
最直接的方式就是在loader外部先定义一个变量,加载完成后把FBX对象赋值给它,后续就能在外部安全访问:
// 在外层作用域声明变量 let logo = null; const loader = new FBXLoader(); loader.load('{{asset('models/model.fbx')}}', function (loadedLogo) { logo = loadedLogo; scene.add(logo); logo.position.set(0, 0, 0); // 用set方法一次性设置xyz更简洁 logo.updateMatrix(); }); // 在animate或其他函数中使用时,先判断对象是否加载完成 function animate() { requestAnimationFrame(animate); if (logo) { // 这里可以放心操作logo的属性,比如添加旋转动画 logo.rotation.y += 0.01; } renderer.render(scene, camera); } animate();
这种写法不用把所有逻辑塞进loader回调,既保持代码结构清晰,又能避免未加载完成时操作空对象的错误。
方法2:用Promise封装加载逻辑
如果项目里习惯用async/await,把加载过程封装成Promise会更优雅,尤其适合多模型加载的场景:
function loadFBXModel(url) { return new Promise((resolve, reject) => { const loader = new FBXLoader(); loader.load( url, (model) => resolve(model), undefined, // 进度回调可选,不需要可以留空 (error) => reject(error) ); }); } // 用async函数初始化场景 async function initScene() { try { const logo = await loadFBXModel('{{asset('models/model.fbx')}}'); scene.add(logo); logo.position.set(0, 0, 0); // 直接把logo传递给animate函数使用 animate(logo); } catch (err) { console.error('模型加载失败:', err); } } function animate(logo) { requestAnimationFrame(() => animate(logo)); logo.rotation.y += 0.01; renderer.render(scene, camera); } initScene();
方法3:自定义事件通知加载完成
如果不想用全局变量或Promise,也可以通过自定义事件通知外部对象已加载完成:
const loader = new FBXLoader(); loader.load('{{asset('models/model.fbx')}}', function (logo) { scene.add(logo); logo.position.set(0, 0, 0); logo.updateMatrix(); // 触发自定义事件,把logo对象通过事件传递出去 const loadedEvent = new CustomEvent('modelLoaded', { detail: logo }); window.dispatchEvent(loadedEvent); }); // 外部监听自定义事件,拿到logo对象后再操作 window.addEventListener('modelLoaded', (e) => { const logo = e.detail; function animate() { requestAnimationFrame(animate); logo.rotation.y += 0.01; renderer.render(scene, camera); } animate(); });
以上几种都是行业内常用的规范写法,不用把所有逻辑塞进回调函数,能有效保持代码的可维护性。
内容的提问来源于stack exchange,提问作者Mike
相关产品推荐
相关产品推荐

