首页 > 解决方案 > 指针事件未在 react-three-fiber 中触发

问题描述

我正在尝试将指针事件添加到使用 GLTFJSX 加载到 react-three-fiber 中的 GLTF 文件中。但是,指针事件不会触发,我不知道为什么。

我已经尝试将相同的事件添加到其他类似的代码沙箱中,并且它可以工作 - 那么如果我在做基本相同的事情,为什么它不能在这个示例中工作?

https://codesandbox.io/s/hopeful-brook-h8rhs?file=/src/App.js

有时,onPointerOverandonPointerOut事件确实有效。这似乎是随机起作用的——有时它起作用,但大多数时候它只是不起作用。

我错过了一些明显的东西吗?

编辑

当更改为mesh时,指针事件起作用。skinnedMesh所以这个问题与不检测指针事件直接相关。

标签: three.jsreact-three-fiber

解决方案


问题在于SkinnedMesh修改了图形卡(GPU)中的顶点位置,因此 JavaScript 端在执行命中测试(也称为 Raycasting)时不知道顶点已被移动。看看下面的截图:

网:

当您使用Mesh时,顶点显示在geometry.attributes.position指示的位置。形状小而远,但您的鼠标事件按预期工作。 在此处输入图像描述

蒙皮网格:

使用SkinnedMesh时,顶点在 GPU 中被平移得更近,但光线投射计算仍使用原始geometry.attributes.position坐标进行命中测试。这就是为什么您只能在红框内的一个非常小的区域内获得预期的鼠标事件。 在此处输入图像描述

解决方案:

解决方案因您的用例而异,但您可以执行以下任何操作:

  1. 使用Mesh,并更新mesh.position属性以将其移近相机。
  2. 如果需要SkinnedMesh,请尽量保持骨架位移足够小,以使其蒙皮位置不会偏离其原始位置太远。
  3. 您可以创建一个不可见的“hitbox”,然后将鼠标事件添加到其中。这是大多数游戏开发人员使用的方法,因为它可以更快地针对非常简单的几何体计算命中测试:
var hitGeom = new THREE.BoxBufferGeometry(1, 1, 1);
var hitMat = new THREE.MeshBasicMaterial({visible: false});
// ...
<mesh geometry={hitGeom} material={hitMat}>

推荐阅读