您如何在2物理引擎(如farseer / box2d)中遵循AI路径?


12

我正在将自己一直在努力的2d自上而下游戏移植到像Farseer这样的合适的刚体物理引擎中。到现在为止,我只是在需要的地方才编写了自己的物理代码。

我正在尝试在这里学习正确的做事方式。

一旦在物理引擎内部使它们成为刚体,使AI遵循设定路径的正确方法是什么?

如果我在地图上有需要AI遵循的导航节点路径,那么以前,我会通过沿下一个步骤计算它们应位于的下一个位置并将其手动设置为该位置来手动沿路径移动它们。

但是现在它们是刚体,容易受到碰撞以及任何可能撞击它们并将其击落的力。

因此,为了使AI向前迈进,我相信我现在应该向它们施加冲动/力量了吗?我不应该再手动设置每个帧的位置。

因此,我认为我需要从一个确定性世界出发,在这个世界中,我必须迫使AI严格遵循一个不确定性世界,在这种情况下,如果受到撞击,它们可能会在任何方向被撞倒,我只是将它们轻推到路径中的下一个节点让他们动起来。

是对的吗?那是别人怎么做的吗?

这就引发了一些问题,即如何避免您的AI一直走在不正确的道路上,而又如何避免它们卡在风光的拐角处?你们如何处理这种事情呢?

还是以某种方式将两者混合并让您的AI通过手动设置其位置而遵循固定的路径,并且仅在您可以轻松控制的某些情况下对其他作用力做出反应,才更好呢?

感谢您的任何建议。


1
+1我也很想了解这一点。
David Gouveia

Answers:


7

转向行为与物理引擎结合使用时效果很好,因为它们通常以返回“转向力”的方式实施,然后可以将其应用于您的物理身体。

要使单元遵循路径,可以使用“ 搜索”从路径节点到路径节点(请确保避免过冲),然后在路径的最后一个节点使用“ 到达 ”。

至于您对卡住的担忧:使用力对路径进行建模实际上应该是非常准确的。没错,如果一个对象与另一个对象发生碰撞,它可能会从路径上抛出,但是由于您将在每次更新中计算出转向力,因此该对象应该立即恢复正常。如果碰撞后与路径的偏差可能很大,那么我建议您在发生碰撞时记住您的最后位置,然后在继续正常路线之前将物体转向到该最后位置。


很棒的文章,谢谢分享。拯救了我的一天。
里卡多·桑切斯·塞兹

0

我想说您走在正确的道路上,您可能想看一下这篇文章:

http://www.policyalmanac.org/games/aStarTutorial.htm

它解释了使用A *算法的一些基本的避免碰撞和寻路的方法。

编辑:

如果您真的只需要以正确的方向推动物体的最佳方法是什么,则应该使用力(例如,MovingForce之类的东西)指向使用您的路径查找算法找到的最佳路径的方向。选择


我认为这篇文章与这个问题无关。OP并不是在问如何找到两个位置之间的最佳路径,而是在物理模拟的背景下如何让演员遵循他已经计算出的路径。
David Gouveia

好吧,当我再次阅读它时,我明白了您的意思,我会编辑我的答案
匿名

:)我也更改了标题以清除内容。对路径遵循绝对感兴趣,而不是寻找路径。
TerryB

0

根据@davidluzgouveia对匿名发布的评论,我将启动我的项目。但是,路径跟随和路径查找是非常不同的。路径查找更多是匿名发布的内容,对于路径查找,我将研究Dijkstra的算法。对于路径跟踪,我将完全使用我选择的物理引擎。我设置的方式是,单元类要通过的2D偏移量在它的路径子类中设置每个位置,因此是2D而不是3D,这是因为我在游戏中设置了物理方法。

3D解释: 每个单元只有一个主碰撞器,专门为与地形和世界物体碰撞而设置。从程序上讲,它是一个胶囊形状,具有半径和高度。它建立在模型的中心,应该延伸到模型的顶部和顶部。但是我也有一个表面偏移量,该偏移量始终是在离地面多远的位置,并且有一次浮动,允许它向下滑动然后一次略微弹起多少。这听起来像是我为地形碰撞问题应用了某种固定的解决方法,但是我有自己的理由。

无论如何,您都应向此胶囊对象施力,并且它应始终保持悬停在地面上。这并不是说它不能再走高,只是它不能再走低。它需要悬停的原因(在我的情况下)是因为在刚体和布娃娃物理引擎中,我的单元的腿会按照程序进行动画处理。因此,通过向胶囊施加简单的力,我实体的腿将自行重新定位。他们还将有各自的重力应用程序!这样做是为了让我的角色倾斜时,一只脚的高度可以比另一只脚的高度低。

这正是您应该做的。根据您的要求判断。如果您想保留一些功能,那显然很好,尤其是在RTS或FPS上,而没人会反正脚部或在乎。但通常,该单元应具有一个MAIN碰撞对象,几乎可以与角色移动一起工作。

特别是2D: 您仍然应该有一个主要要点,或者只是某种参考,以便引擎能够推动运动,这是一个单元的运动。您可以为每个单元提供一个路径子类,该子类具有一些需要去的位置,您可以在级别代码中指定它(例如location1(x,y)location2(x,y)等),最好的方法是(不知道您正在从事哪种游戏)可能是在关卡中指定位置,并让每个单元按关卡指定的顺序处理它们,并在到达每个位置后,将其替换为所需的位置下一个需要到达的地方。

您可以通过多种方式进行修改,例如,首先为每个单元找到一个位置列表,因为这意味着并非所有单元都必须移到相同的位置。但是,以同样的方式,您也可以在级别代码中执行此操作(unit1.location1(x,y)unit1.location2(x,y)grunt.l1(x,y)knight.loc3(x,y)随你)

只是一些想法!我建议您阅读3D版本,即使它的相关性远不如此。

编辑:我决定只为可能读过此书的任何人提供这两个文件(是的,是的)....(我最初只是略过您的问题,直到我重读它才意识到这是2D特有的。>)

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.