【问题标题】:Pointer events not firing in react-three-fiber指针事件未在 react-three-fiber 中触发
【发布时间】:2021-04-04 16:44:41
【问题描述】:

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

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

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

  • 预期行为:当您将鼠标悬停在模型上或单击它时,它应该会记录到控制台。
  • 实际行为:只有 onPointerMissed 事件会触发。

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

我是否遗漏了一些明显的东西?

编辑

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

【问题讨论】:

    标签: three.js react-three-fiber


    【解决方案1】:

    问题是SkinnedMesh修改了显卡(GPU)中的顶点位置,所以JavaScript端在执行hit-test(也称为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}>
    

    【讨论】:

    • 非常有趣,我什至没有想到。感谢您的回复和详尽的解释。在这种情况下,我确实需要 skinnedMesh。我之前尝试过使用碰撞箱,但由于需要对其进行动画处理,我认为同时为模型和碰撞箱设置动画会更加困难。所以我会尝试从 Blender 解决这个问题,保持网格和 skinnedMesh 对齐。
    猜你喜欢
    • 2020-10-31
    • 2022-01-04
    • 1970-01-01
    • 2021-08-20
    • 2021-03-09
    • 2021-05-22
    • 2019-10-27
    • 2022-01-25
    • 1970-01-01
    相关资源
    最近更新 更多