如何修复Three.js循环加载GLTF模型时读取undefined的length属性错误
问题定位与修复方案
错误原因
- 核心逻辑错误:
GLTFLoader.load()是异步API,你将scene.add(gltf.scene)、roughnessMipmapper.dispose()、render()这三段代码写在了加载完成的回调函数外部,代码执行到这几行时模型还未加载完成,gltf对象为未定义状态,访问gltf.scene触发异常,最终导致three内部读取对象属性时抛出Cannot read properties of undefined (reading 'length')错误。 - 语法错误:代码末尾存在多余的
});闭合符号,会引发语法解析异常。 - 逻辑时序错误:
roughnessMipmapper.dispose()不能放在单次模型加载逻辑中,需要在所有模型的材质mipmap生成完成后再调用,提前调用会导致后续加载的模型无法正常生成mipmap。
修复后代码
const loader = new GLTFLoader() .setPath( 'resources/' ); const resourceData = ["Learning Bee1","Learning Bee2","Learning Bee3"]; // 统计已加载完成的模型数量,用于判断是否全部加载完毕 let loadedCount = 0; for(let i=0; i<resourceData.length;i++){ let oResource = resourceData[i]; let sModelName = oResource + ".gltf"; loader.load( sModelName, function ( gltf ) { gltf.scene.traverse( function ( child ) { if ( child.isMesh ) { roughnessMipmapper.generateMipmaps( child.material ); } }); // 模型加载完成后再添加到场景 scene.add( gltf.scene ); loadedCount++; // 所有模型加载完成后统一执行dispose和渲染 if(loadedCount === resourceData.length) { roughnessMipmapper.dispose(); render(); } }); }
优化建议
- 可以用
Promise封装批量加载逻辑,更方便统一处理所有模型加载完成后的回调操作。 - 可以给
loader.load添加第三个错误回调参数,排查是否存在模型资源路径错误、资源损坏的问题。
内容的提问来源于stack exchange,提问作者Nirodha Lakmali
相关产品推荐
相关产品推荐

