Three.js网格点击事件报错求助:Cannot read properties of undefined (reading 'setFromCamera')
解决Three.js网格点击事件中的
Cannot read properties of undefined (reading 'setFromCamera')错误 这个错误的核心是当调用raycaster.setFromCamera()时,raycaster变量的值是undefined,结合你使用Angular的场景,我帮你梳理几个最可能的原因和对应的修复方案:
1. 变量作用域与Angular组件上下文问题
在Angular中,直接用var声明全局变量很容易导致上下文丢失或者变量未正确初始化。正确的做法是把raycaster、mouse和targetMesh作为组件类的属性,确保它们始终属于组件实例:
// 在你的组件类中定义属性 private raycaster!: THREE.Raycaster; private mouse!: THREE.Vector2; private targetMesh?: THREE.Mesh; private camera!: THREE.Camera; // 确保camera也是组件类的属性 ngOnInit() { // 在组件初始化时创建实例 this.raycaster = new THREE.Raycaster(); this.mouse = new THREE.Vector2(); // 初始化你的目标网格(示例:创建一个立方体) const geo = new THREE.BoxGeometry(1, 1, 1); const mat = new THREE.MeshBasicMaterial({ color: 0x4287f5 }); this.targetMesh = new THREE.Mesh(geo, mat); this.scene.add(this.targetMesh); // 假设scene是你已创建的场景对象 // 绑定事件时要确保回调函数的上下文指向组件实例 window.addEventListener('click', this.onMouseClick.bind(this), false); window.addEventListener('mousemove', this.onMouseMove.bind(this), false); }
2. 错误的事件名称
你的代码里用了mouseclick事件,但浏览器标准的点击事件名称是click,虽然这个不会直接导致raycaster未定义,但会让你的点击回调永远触发不了,必须修正:
// 把mouseclick替换为click window.addEventListener('click', this.onMouseClick.bind(this), false);
3. 修复点击回调的逻辑错误
另外还要注意,raycaster.intersectObject()返回的是相交对象的数组,不是布尔值。你原来的if(isIntersected)判断是错误的,空数组在JavaScript里会被判定为true,所以要改成判断数组长度:
onMouseClick(event: MouseEvent) { this.raycaster.setFromCamera(this.mouse, this.camera); // 确保targetMesh已初始化,用!非空断言或者可选链 const intersects = this.raycaster.intersectObject(this.targetMesh!); if (intersects.length > 0) { console.log('Mesh clicked!'); } }
4. 避免内存泄漏(Angular额外注意点)
在Angular组件销毁时,记得移除事件监听器,防止内存泄漏:
ngOnDestroy() { window.removeEventListener('click', this.onMouseClick.bind(this)); window.removeEventListener('mousemove', this.onMouseMove.bind(this)); }
按照这些步骤调整后,你的网格点击事件应该就能正常工作了。
内容的提问来源于stack exchange,提问作者Arjun M Nair
相关产品推荐
相关产品推荐

