英文:
ThreeJS model loader failed to load when used inside a class method
问题
我正在尝试构建一个ThreeJS场景,并将其编码为一个类:
export class RenderCanvas {
#scene; // THREE.Scene()
// 其他属性和方法
loadGeometries() {
/* 在调用loadGeometries之前,#scene已经被初始化 */
var modelLoader = new FBXLoader();
for (let path of listOfObjects) {
modelLoader.load(path,
function (obj) {
obj.traverse(function (child) { /* 什么也没做 */ });
this.#scene.add(obj);
},
function (xhr) {
console.log((xhr.loaded / xhr.total * 100) + "% loaded")
},
function (err) {
console.error("加载对象时出错")
}
)
}
}
}
在另一个JS文件中,实例化了一个RenderCanvas
类,并调用了loadGeometries()
方法。
控制台显示模型加载到了100%,但随后触发了Error loading the object
错误。
我注意到,如果我使用过程式的方式而不是面向对象编程,并将scene
作为全局变量,那么模型加载器就能正常工作。所以我猜测问题可能与this.#scene.add(obj);
缺少上下文有关,但我不确定是否确实是这种情况,也不知道如何修复。
出了什么问题,我该如何修复?
英文:
I'm trying to build a ThreeJS scene and have been coding it as a class:
export class RenderCanvas {
#scene; // THREE.Scene()
// Other properties and methods
loadGeometries() {
/* #scene is initialized prior to loadGeometries being called */
var modelLoader = new FBXLoader();
for (let path of listOfObjects) {
modelLoader.load(path,
function (obj) {
obj.traverse(function (child) { /* did nothing */ });
this.#scene.add(obj);
},
function (xhr) {
console.log((xhr.loaded / xhr.total * 100) + "% loaded")
},
function (err) {
console.error("Error loading the object")
}
)
}
}
In another JS file, a RenderCanvas
class is instantiated and has the loadGeometries()
method called.
The console showed that the model is loaded to 100%, but then the Error loading the object
is triggered.
I noticed that if I use the procedural way instead of OOP and have scene
as a global variable, then the model loader would work. So I am assuming that it has something to do with this.#scene.add(obj);
missing the context, but have no idea if this is indeed the case or how to fix that.
What went wrong and how may I fix it?
答案1
得分: 1
似乎this
指向的引用不正确,因为你在onLoad()
回调函数内部。尝试将this
引用保存在一个scope
变量中。类似这样:
loadGeometries() {
/* #scene在调用loadGeometries之前已经初始化 */
var modelLoader = new FBXLoader();
var scope = this;
for (let path of listOfObjects) {
modelLoader.load(path,
function (obj) {
obj.traverse(function (child) { /* 未做任何操作 */ });
scope.#scene.add(obj);
},
function (xhr) {
console.log((xhr.loaded / xhr.total * 100) + "% 已加载");
},
function (err) {
console.error("加载对象时出错");
}
);
}
}
或者,使用箭头函数而不是普通函数,因为箭头函数保留了this
引用。
英文:
It seems this
does not point to the right reference since you are inside the onLoad()
callback. Try to save the this
reference in a scope
variable. Something like:
loadGeometries() {
/* #scene is initialized prior to loadGeometries being called */
var modelLoader = new FBXLoader();
var scope = this;
for (let path of listOfObjects) {
modelLoader.load(path,
function (obj) {
obj.traverse(function (child) { /* did nothing */ });
scope.#scene.add(obj);
},
function (xhr) {
console.log((xhr.loaded / xhr.total * 100) + "% loaded")
},
function (err) {
console.error("Error loading the object")
}
)
}
}
Alternatively, use an arrow function instead of normal one since the former one retains the this
reference.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论