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

ThreeJS类方法中FBXLoader加载模型失败问题排查与解决

问题原因

核心问题是FBXLoader回调函数的this上下文丢失。在类的方法中调用loader.load()时,onLoad/onError这类回调默认的this指向FBXLoader实例,而非你的RenderCanvas类实例。当你在回调里尝试访问this.#scene(私有属性)时,由于Loader实例没有该属性,会抛出隐性错误,最终触发错误回调——这就是模型加载进度到100%(资源本身无问题)却报错的根本原因。

修复方案

以下三种方式都能解决上下文绑定问题,选你习惯的即可:

方案1:使用箭头函数绑定上下文

箭头函数会自动继承外层作用域的this(即RenderCanvas实例),直接在回调中使用:

class RenderCanvas {
  #scene;

  constructor() {
    this.#scene = new THREE.Scene();
    // 其他初始化逻辑
  }

  loadGeometries(modelPaths) {
    const loader = new THREE.FBXLoader();
    modelPaths.forEach(path => {
      loader.load(
        path,
        // 箭头函数继承外层this
        (model) => {
          this.#scene.add(model);
          // 其他加载成功逻辑
        },
        (progress) => {
          console.log(`加载进度:${Math.floor(progress.loaded / progress.total * 100)}%`);
        },
        (error) => {
          console.error('加载失败:', error);
        }
      );
    });
  }
}

方案2:用bind()手动绑定this

在类的构造函数中,把回调函数的this绑定到当前实例:

class RenderCanvas {
  #scene;

  constructor() {
    this.#scene = new THREE.Scene();
    // 绑定回调的this到类实例
    this.handleModelLoad = this.handleModelLoad.bind(this);
    this.handleLoadError = this.handleLoadError.bind(this);
  }

  handleModelLoad(model) {
    this.#scene.add(model);
    // 其他成功逻辑
  }

  handleLoadError(error) {
    console.error('加载失败:', error);
  }

  loadGeometries(modelPaths) {
    const loader = new THREE.FBXLoader();
    modelPaths.forEach(path => {
      loader.load(
        path,
        this.handleModelLoad,
        (progress) => {
          console.log(`加载进度:${Math.floor(progress.loaded / progress.total * 100)}%`);
        },
        this.handleLoadError
      );
    });
  }
}

方案3:提前保存this到变量

在loadGeometries方法开头,把当前实例的this存到变量中,回调里用该变量访问类属性:

class RenderCanvas {
  #scene;

  constructor() {
    this.#scene = new THREE.Scene();
  }

  loadGeometries(modelPaths) {
    const loader = new THREE.FBXLoader();
    const self = this; // 保存当前实例的引用
    modelPaths.forEach(path => {
      loader.load(
        path,
        function(model) {
          self.#scene.add(model); // 用self代替this
        },
        function(progress) {
          console.log(`加载进度:${Math.floor(progress.loaded / progress.total * 100)}%`);
        },
        function(error) {
          console.error('加载失败:', error);
        }
      );
    });
  }
}

内容的提问来源于stack exchange,提问作者Amarth Gûl

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 18:33:24