You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 04:54:02