网格导入设置刷新ctrl + R在raycastHit点计算中的影响

问题描述

不要因为它的长度而害怕这个问题。其实这个问题很简单也很有趣,相信很容易上手,但是我想好好解释一下。无论如何,如果您愿意,感谢您的阅读:)

出于不相关的原因,我执行以下操作,从从光线投射中检索到的点,我向上走一米,然后向下投射另一条光线,以获得地面点。请参阅“我为什么要这样做?”最后是上下文,与问题无关。只是为了解释为什么从一个 raycasthit 点会是从另一个 raycast 重新计算的同一点。

对于这种情况,检索到的点应该完全相同。在代码中查看为什么当从 完全相同的点 上方一定距离抛出光线投射时,应该检索 完全相同的点 作为起点是有意义的用raycast检索,代码其实很简单:

    if (Physics.Raycast(ray,out RaycastHit result1,maxdistance,mask,triggerInteraction))
    { 
        Debug.LogError($"main camera picked point: {result1.point.x:G9},{result1.point.y:G9},{result1.point.z:G9}");
        if (Physics.Raycast(result1.point + Vector3.up * 1,-Vector3.up,out RaycastHit result2,32,mask))
        { 
            Debug.LogError($"1m up from above raycast point: {result2.point.x:G9},{result2.point.y:G9},{result2.point.z:G9}");
        }
        returnValue = true;
    }

第一次光线投射检索世界位置,第二次光线投射从上方 1m 处向下投射光线。考虑到它是完全相同的点,因为原点是 result1.point + Vector3.up * 1。记录所有小数点的点,这就是为什么我强调它是完全相同的点

问题是,有一个表面不会发生这种情况并且小数会发生变化。像这样:

enter image description here

正如在我偶然发现问题之前所说的,检索到的点完全相同:

enter image description here

在精度方面没什么大不了的,但我想知道为什么会发生这种情况。 这个表面有一个网格,有法线、切线等。当我在网格导入设置中删除它们时,问题就消失了,检索到的点是相同的。查看设置的屏幕截图。

来自状态:(点差是如何产生的):

enter image description here

说明(点差如何产生):

enter image description here

网格法线在 raycasthit 计算中有什么影响?。任何可以检查光线投射在幕后如何工作的资源?

我为什么要这样做?

它与问题本身无关,而是根据上下文对其进行解释并避免不必要的答案/评论。 它是将空间路径中的一些点移动到地面。该路径的节点(从中检索路径的参考点)已经存在于地面中(从主摄像机抛出以使用光线投射“挑选”世界点以定义路径节点)。所以我不需要找到节点本身的地面点,因为它们已经在地面上,但没有必要这样做,因为我正在遍历我偶然发现这个问题的所有路径点。

感谢阅读。

编辑:在网格导入设置中删除法线,按照统一 docs 建议:“优化提示:如果网格碰撞器仅使用网格,您可以在导入设置中禁用法线,因为物理系统不需要它们。” 但是,如果我以无法线启动应用程序,并在设置导入选项 + ctrl + R 后,您会得到一个不同的点,法线设置为无,而在设置法线导入选项后得到准确的点。因此,它似乎与在运行时更改选项 + 重新编译以及网格烹饪的事实有关,而不是专门使用网格法线。

网格形状图像,从上方红色箭头方向投射光线:

enter image description here

解决方法

一般来说,不能保证在同一点命中!

想象以下(原谅我惊人的绘画技巧^^)

enter image description here

所以一般来说,你的检查没什么意义,除非你总是可以 100% 确定你的第二条射线不会意外地从网格的另一侧发射。


如果使用非凸面的 Mesh,情况会更糟,因为您很容易在第一次击中凹孔并第二次从外面击中它。


另一个重要的问题是:你的第二次光线投射是否击中了同一个物体?

Debug.Assert(result1.collider == result2.collider,"Oh oh that could explain things");

在您的情况下,另一个原因可能是没有法线的 MeshCollider 的 Mesh 可能针对物理优化与具有法线的不同。根据优化设置(“烹饪选项”),MeshCollider 的形状不是 100% 与实际的 Mesh 形状相同。