传递给构造函数的world参数为何变为undefined?
Three.js + Cannon.js 错误:Cannot read properties of undefined (reading 'copy')
错误信息
Uncaught TypeError: Cannot read properties of undefined (reading 'copy') at World.add.World.addBody (cannon.js:12985:23) at new BothObject (objects.js:15:16) at new Cube (objects.js:33:5) at script.js:7:15
相关代码
objects.js
class BothObject{ constructor(shape,geometry,mass,color,scene,world){ this.scene=scene this.world=world this.physics = new CANNON.Body({ mass: mass, // kg }); this.physics.shape=shape this.geometry = geometry; this.material = new THREE.MeshPhongMaterial( { color: color}); this.mesh = new THREE.Mesh(this.geometry,this.material) console.log(world) this.scene.add(this.mesh) this.world.addBody(this.physics) } update(){ this.mesh.position.copy(this.physics.position) this.mesh.quaternion.copy(this.physics.quaternion) } } class Sphere extends BothObject{ constructor(radius,mass,color,scene,world){ super(new CANNON.Sphere(radius/2),new THREE.SphereGeometry(radius),mass,color,scene,world) } } class Cube extends BothObject{ constructor(width,height,depth,mass,color,scene,world){ super(new CANNON.Box(new CANNON.Vec3(width/2,height/2,depth/2)),new THREE.BoxGeometry(width,height,depth),mass,color,scene,world) } }
script.js
console.log("start") const scene = new THREE.Scene(); scene.background = new THREE.Color( 'skyblue' ); var world = new CANNON.World(); world.gravity.set(0,0,-9.82); var gground = new Cube(100,100,0.1,"green",scene,world)//it's gground because I have another variable named ground
问题现象
- script.js中打印
world正常,但在Cube或BothObject中打印world显示undefined - 调用
this.world.addBody(this.physics)时触发错误,因为this.world是undefined
原因与解决方法
原因
Cube构造函数定义了7个参数:width,height,depth,mass,color,scene,world,但在script.js调用时只传了6个参数:100,100,0.1,"green",scene,world。参数顺序不匹配导致最后一个world参数未被正确传入,变成了undefined,进而在BothObject中调用this.world.addBody时出错。
解决方法
在调用Cube时补充传入mass参数(地面通常设置mass=0使其固定不动),修正参数顺序:
// script.js中修正调用代码 var gground = new Cube(100,100,0.1, 0, "green", scene, world)
或者修改Cube的构造函数参数顺序,让参数对应更合理:
// objects.js中修改Cube构造函数 class Cube extends BothObject{ // 调整参数顺序为width,height,depth,color,mass,scene,world constructor(width,height,depth,color,mass,scene,world){ super(new CANNON.Box(new CANNON.Vec3(width/2,height/2,depth/2)),new THREE.BoxGeometry(width,height,depth),mass,color,scene,world) } }
两种方案选其一即可,推荐第一种,保持构造函数参数顺序和super调用逻辑一致更清晰。
内容的提问来源于stack exchange,提问作者noob10293
相关产品推荐
相关产品推荐

