Three.js如何在GLTF加载器外部获取加载的gltf.scene模型对象
问题核心原因
你的问题确实由异步加载导致:GLTFLoader的加载逻辑是非阻塞的,调用加载方法后代码会直接向下执行,不会等待资源请求、解析完成。同时JavaScript类的constructor不支持await语法,因此你在constructor中同步读取this.character时,加载逻辑还未执行完成,变量自然为undefined。
解决方案1:使用异步静态工厂方法创建实例(最推荐)
这是规避constructor不能异步的最规范方案,先完成资源加载再返回初始化完成的实例:
class MainCharacter { // 构造函数改为接收预加载好的gltf资源 constructor(game, gltf) { this.game = game; this.character = gltf.scene; this.character.scale.set(13, 13, 13); // 其他初始化逻辑 } // 异步静态工厂方法,负责资源加载和实例创建 static async create(game) { const loader = new GLTFLoader(); const gltf = await loader.loadAsync("./c.glb"); // 资源加载完成后再创建实例返回 return new MainCharacter(game, gltf); } } // 外部调用方式 async function initGame() { const mainCharacter = await MainCharacter.create(game); console.log(mainCharacter.character); // 此时可以正常拿到加载好的模型 } initGame();
解决方案2:暴露加载完成的Promise供外部等待
如果你不想改动实例创建的逻辑,可以给类挂载一个加载状态的Promise,外部需要使用模型时等待该Promise完成即可:
class MainCharacter { constructor(game) { this.game = game; this.character = null; // 存储加载完成的Promise,外部可直接await这个属性 this.loaded = this.loadMain(); } async loadMain() { const loader = new GLTFLoader(); const gltf = await loader.loadAsync("./c.glb"); this.character = gltf.scene; this.character.scale.set(13, 13, 13); this.scene.add(this.character); return this.character; } } // 外部调用方式 async function useCharacter() { const mainCharacter = new MainCharacter(game); const character = await mainCharacter.loaded; console.log(character); // 正常获取模型 }
解决方案3:使用回调函数通知加载完成
适合简单场景,加载完成后执行传入的回调函数:
class MainCharacter { constructor(game, onLoadComplete) { this.game = game; this.character = null; const loader = new GLTFLoader(); loader.load("./c.glb", (gltf) => { this.character = gltf.scene; this.character.scale.set(13, 13, 13); this.scene.add(this.character); // 加载完成触发回调 onLoadComplete?.(this.character); }); } } // 外部调用方式 const mainCharacter = new MainCharacter(game, (character) => { console.log(character); // 回调中拿到加载完成的模型 });
注意:所有需要用到模型的逻辑,都必须确保在资源加载完成后执行,不要在constructor中同步读取还未完成加载的异步资源。
内容的提问来源于stack exchange,提问作者MiMi
相关产品推荐
相关产品推荐

