Three.js使用GLTFLoader加载模型时报Cannot read properties of undefined错误如何解决
问题原因
该错误和作用域无关,是由GLTFLoader.load()的异步执行特性导致的。JS执行代码时会优先跑完所有同步逻辑,再执行异步回调,你写在加载函数外部的sculpture.scale.z = 1属于同步代码,执行时模型还未完成加载,回调函数内的sculpture = gltf.scene赋值逻辑还未触发,此时sculpture还是初始的undefined,因此读取scale属性会抛出错误。
修复方案
方案1:把模型操作逻辑放入加载回调
适合简单的单次操作,直接把要执行的属性修改放到loader的成功回调里,确保模型加载完成后才执行:
let sculpture const loader = new THREE.GLTFLoader() const modelFile = require(`./assets/Sculpture_lo5.glb`) loader.load(modelFile, (gltf) => { sculpture = gltf.scene sculpture.scale.set(0.35,0.35,0.35) scene.add(sculpture) // 所有模型相关操作都放在回调内执行 sculpture.scale.z = 1 })
方案2:封装为Promise方便多场景调用
如果需要在多个不同的函数里操作模型,可以把加载逻辑封装成Promise,后续通过.then()或者await调用,避免回调嵌套:
// 封装加载方法 function loadModel() { return new Promise((resolve, reject) => { const loader = new THREE.GLTFLoader() const modelFile = require(`./assets/Sculpture_lo5.glb`) loader.load(modelFile, (gltf) => { const sculpture = gltf.scene sculpture.scale.set(0.35,0.35,0.35) scene.add(sculpture) resolve(sculpture) }, undefined, reject) }) } // 调用加载,后续所有模型操作都可以在then里执行 loadModel().then(sculpture => { sculpture.scale.z = 1 // 其他动画操作也可以在这里调用 // startAnimation(sculpture) })
方案3:渲染循环中加存在性判断
如果是要在全局的渲染/动画循环里修改模型属性,可以加判断,确认模型加载完成后再执行操作:
let sculpture const loader = new THREE.GLTFLoader() const modelFile = require(`./assets/Sculpture_lo5.glb`) loader.load(modelFile, (gltf) => { sculpture = gltf.scene sculpture.scale.set(0.35,0.35,0.35) scene.add(sculpture) }) function animate() { requestAnimationFrame(animate) // 操作前先判断sculpture是否已经被赋值 if (sculpture) { sculpture.scale.z = 1 // 其他动画逻辑 } renderer.render(scene, camera) } animate()
内容的提问来源于stack exchange,提问作者user15635022
相关产品推荐
相关产品推荐

