在运行时更新网格对撞机的替代方案?
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 中创建自己的边缘测试实现。如果它们不是太多,这可能会更快。然后,您还可以指定如果几何形状的变化突然导致玩家出界时如何表现。
缺点是必须处理弹性、阻尼等问题。
【讨论】:
以上是关于在运行时更新网格对撞机的替代方案?的主要内容,如果未能解决你的问题,请参考以下文章
ASP.NET MVC 5 实体框架替代方案或在运行时指定架构的能力?