【问题标题】:Mesh import settings refresh (ctrl + R) influence in raycastHit point calculation网格导入设置刷新(ctrl + R)对raycastHit点计算的影响
【发布时间】:2021-08-02 15:13:53
【问题描述】:

不要害怕这个问题,因为它很长。事实上,这个问题很简单也很有趣,我相信很容易理解,但我想适当地解释一下。如果您选择这样做,无论如何感谢您的阅读:)。

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

在这种情况下,检索到的点应该完全相同。在代码中查看为什么当从 exact same point 上方抛出某个距离上方的光线投射时,应该检索 exact same point 作为起始点是有意义的用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。记录所有小数点,这就是为什么我强调它是完全相同的点

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

正如我在遇到问题之前所说的那样,检索到的点完全相同:

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

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

陈述(点差如何产生):

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

我为什么要这样做?

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

感谢阅读。

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

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

【问题讨论】:

    标签: unity3d collision-detection collision physics-engine


    【解决方案1】:

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

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

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


    如果网格不是凸面的,情况会变得更糟,因为您很容易第一次撞到凹孔,第二次从外面撞到它。


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

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

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

    【讨论】:

    • 非常感谢您的回答。我将对您的 cmets 提出一些观点 1.- 绘图已经足够好了^^。这对我来说很明显,但不是问题,所以感谢您发现了这一点。射线投射命中的物体在随机旋转中不是随机形状的。它是一个平面,就像一个水平三角形,光线应该在同一个地方打到,图片的情况是不可能发生的。
    • 2.- 确实,网格不是凹的。我知道这会对碰撞产生影响,但认为这与这种情况无关,因为碰撞被正确检测到。形状是一个长而扁平的弯曲矩形(它是一条路径)。从视觉上看,从上表面找到一个点时不会有点差异,因为网格对撞机非常简单(矩形),而且冲击面很清晰,虽然不是凹面
    • 3.- result1.collider == result2.collider 是真的,但这也是一个好点
    • 在第一条评论中,关于平面像水平三角形 = 像水平矩形
    • 4.-“根据优化设置,MeshCollider 的形状与实际的 Mesh 形状不是 100% 相等”。这个问题似乎与这个“网状烹饪”密切相关,但我不明白这个细节。我删除了每个统一文档建议的法线“优化提示:如果网格碰撞器仅使用网格,您可以在导入设置中禁用法线,因为物理系统不需要它们。”但我意识到,如果我做相反的事情,即使用法线启动应用程序为无,然后设置正常的导入选项 + ctrl + R,我会得到相同的结果。问题已更新
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-28
    • 2019-02-26
    • 2016-12-18
    • 1970-01-01
    • 2011-07-28
    • 1970-01-01
    相关资源
    最近更新 更多