在运行时更新网格对撞机的替代方案?

Posted

技术标签:

【中文标题】在运行时更新网格对撞机的替代方案?【英文标题】:Alternatives for updating mesh collider in runtime? 【发布时间】:2017-09-21 17:21:18 【问题描述】:

我正在开发用户在运行时(一直)生成网格的游戏,因此网格有许多顶点,同时有一个 GameObject - 玩家需要在它位于生成的区域时触发事件运行时网格。

这个游戏中的相机是 3D 的,但是这个生成的网格是平面的。在我的附图中,我以顶视图显示它以更好地显示它的外观。

现在我每隔几秒就更新一次 Mesh Collider,但是在生成的网格有越来越多的顶点之后它会很慢。

我相信这是一种非常简单的碰撞方法,所以也许有其他方法可以检测到这种情况,而不是附加到动态生成的网格上的 Mesh Collider?

更新 #1

我知道 Mesh Collider 很慢,不应该在运行时更新。我也知道应该使用像盒子对撞机这样的原语的想法。

但是在这种情况下,当这个平面网格每秒更新(并且它会增长)时,它将有数千个盒子碰撞器,并且每秒都需要添加新的。这种方法也行不通。

更新 #2

我的第二个想法是找到离玩家最近的三角形并为它们创建碰撞器(盒子碰撞器应该是最快的)。但我真的不知道从哪里开始,甚至有可能吗?有人吗?

【问题讨论】:

我不知道对你的情况有什么建议,但是是的,你根本不想更新网格碰撞器(旋转、缩放和平移也是个问题)。正是因为您来寻求帮助的原因:重新计算非常昂贵。 是的..我知道.. :(。使用盒子对撞机也不是一个解决方案,因为一段时间后它将有数千个盒子对撞机,我认为这对性能也不利:// 看你生成的网格,是不是不能用LineRenderer的来达到这样的效果? @Hristo 也许可以使用 LineRenderer 但这对碰撞有什么帮助? @seek 你可以检测到你的GameObject/Player 是触线还是触线 【参考方案1】:

如果网格碰撞器适用于小部分而不是全长,则生成多个网格碰撞器,随着玩家绘制更长的路径,每 X 个多边形或 X 个路径长度断开一个新的碰撞器。

【讨论】:

此外,您可以禁用“太远”的碰撞器以提高性能【参考方案2】:

您可以使用光线投射——它通常需要一个碰撞器,但我找到了this(用于在网格上投射光线的脚本,没有碰撞器),我相信您可以在您的情况下使用它。

然后,您可以在生成的网格中引入不可见的背景,并使用光线投射来检测首先被击中的内容。如果您的玩家保持正方形,您可以从 4 个角投射一条光线,如果所有 4 条光线都射到网格上,您就知道自己在上面。

在重叠的情况下,由于链接中的代码可以检测到同一条射线击中的多个三角形,如果击中的三角形的数量大于 1,则您知道您有重叠。您可能可以将顺序用作各种 z-index。

我没有尝试过该代码,但它似乎对其他人有用。希望这会有所帮助!

【讨论】:

【参考方案3】:

如果你想要动态网格碰撞器,你必须使用其他物理引擎,

如果你破坏了unity Mesh collider组件,或者改变了那个组件的sharedMesh,它的性能是非常糟糕的,因为物理引擎必须重建整个新的MeshColldier。

你可以看看这篇文章:

https://forum.unity.com/threads/shadow-of-the-colossus-deformable-mesh-collider.519900/

【讨论】:

【参考方案4】:

你不应该在你的情况下使用任何对撞机。看来您正在使用 3D 相机进行 2D 工作。

你需要的是: 1)将创建的网格绘制到 2D 图片。将网格从第二个正交相机绘制到 RenderTexture,通过过滤标签,您可以获得仅包含网格的顶部查看图片。

2)然后你可以使用这个贴图来计算与你的角色的碰撞:Graphics.Blit你的角色大小的图像到RenderTexture。您应该编写一个接受两种纹理的着色器,一个是贴图,另一个代表您的角色,将角色绘制到您的贴图中,在着色器中将两种颜色混合为一种特殊颜色。最后,你得到了一个混合纹理,你扫描纹理并找出其中的任何特殊颜色,然后做你下一步想做的工作。

【讨论】:

【参考方案5】:

假设这是一种由玩家创建赛道的赛车游戏,我是否正确?实际上,我以前曾尝试过类似的事情。在我的例子中,我创建了一个“Track Segment”对象,基本上是一个扁平的立方体对象,每一帧。我承认这是懒惰的,因为它每帧都创建一个新的盒子碰撞器。但是,我从未以这种方式遇到任何性能问题。

那么,我的建议是将您的网格分割成更小的游戏对象。正如您所描述的,似乎顶点越多性能会变得越差,这样您就可以保持较低的顶点数。

【讨论】:

【参考方案6】:

显然,基于体素的解决方案就是答案。

至于如何实现一个,我不能告诉你细节,因为虽然我知道一般的答案是什么,但我自己从未实现过体素引擎,也没有使用任何现有的引擎。所以我只能为你指出正确的方向。

基本上,不是尝试从任意点创建网格,而是从固定的、有限的、易于优化的点创建它。 Minecraft 以及更复杂的游戏就是这样做的。

Sebastian Lague 在this video 中有一段视频,介绍了与网格生成相关的一些核心内容。

【讨论】:

【参考方案7】:

在解决这个问题的可能方法中,也可以选择不使用任何对撞机,而是在移动对象的 FixedUpdate 中创建自己的边缘测试实现。如果它们不是太多,这可能会更快。然后,您还可以指定如果几何形状的变化突然导致玩家出界时如何表现。

缺点是必须处理弹性、阻尼等问题。

【讨论】:

以上是关于在运行时更新网格对撞机的替代方案?的主要内容,如果未能解决你的问题,请参考以下文章

胶囊对撞机不统一跳跃

在 Unity 中避免粒子和对撞机之间的碰撞

ASP.NET MVC 5 实体框架替代方案或在运行时指定架构的能力?

执行后台任务——AsyncTask 的替代方案?

在 Unity 中导入 Blender,如何生成正确的网格对撞机?

刷新剑道网格,选择框