简单的自上而下的2D游戏船物理

更新:该游戏现已在App Store上以“ Kayak Run”的形式发布。

我一直在研究皮划艇赛车游戏原型。 皮划艇和小船以特定的方式移动,本文报告了我尝试过的方法以及如何解决此问题。

船的龙骨使它具有方向稳定性或“跟踪性”,同时还要权衡一些可操作性。 在我的游戏中,我希望皮划艇在其速度和龙骨平行时轻松行驶,并在其速度和龙骨垂直时体验阻力。 向前推动一艘船很容易,它会走很长时间,但向侧面推动则很困难。

解决方案1:动态线性拖动

在Unity引擎中,我们可以在播放时修改Rigidbody2D.drag 。 为此,我们需要知道船相对于其速度矢量有多“平行”。 龙骨方向和速度之间的角度差可以使用以下公式找到:

  Vector2.Angle(rb.velocity,transform.up) 

Vector2.Angle返回一个介于0到180之间的float 。我们需要弄清楚什么角度等于什么阻力。 值0表示船正在向前行驶,值180表示船正在向后行驶,两者均应与速度平行,因此阻力较小。 90应该是最高阻力。 让我们将角度转换为0到1之间的某个值,以后可以在计算最终阻力时将其用作乘数。

给定我们的角度θ,我们需要一个方程,该方程返回0到1之间的数字。

该方程使图看起来像这样:

在这里,您可以看到对于x值,我们将得到一个y ,该y从0(无阻力)开始,在90°(全阻力)处上升到1,然后在x为180°时又回到0。 然后我们获取输出,将其乘以最大线性拖动,然后将其应用于每帧刚体。

该解决方案有效,但是错过了船物理最有趣的部分。 如果可能的话,皮划艇还应倾向于沿龙骨方向漂移。 这意味着,如果它的速度矢量与龙骨成45°角,即使阻力减慢了它的速度,它也应该拾取少量的向前速度。

解决方案2:反射速度

由于我们希望船根据行进角度来获得前进速度的一部分,因此我们可以重用之前的公式。 但是,与其使用输出来生成动态线性阻力,不如使用它来生成新的力,并使线性阻力保持静态。

为了找到新的力,我们以船的速度为基准,反转船的方向,然后使其偏离中心线。

 Vector2.Reflect(rb.velocity * -1, transform.up) 

我们得到一个新的向量,它为我们的新力量指明了正确的方向。 需要将其减小很多,否则它将淹没您留在刚体上的线性阻力,并永远加速皮划艇运动。 例如,我将我的值乘以0.02。 将此新速度添加到现有的rb.velocity中,您的皮划艇将具有向前和向后漂移的甜蜜行为。 这样即使在没有动力的情况下,皮艇也可以转弯。

下一步

这还没有完成,还有更多我想补充。 例如,我正在使用面积效应器来模拟电流以供玩家导航。 但是,当皮划艇坐在水流中时,它的速度实际上与其自身的速度并不相同,因此它不应向前漂移或受到阻力。 就像小船只是坐在传送带上一样。 由于效应器仅增加力量,因此它们没有速度的概念,因此我无法直接将船速与基础效应器进行比较。 我想我可能最终会创建自己的效应器,但要使其成为速度效应器,而不是力效应器。 如果有人对此有任何经验,我很高兴听到。

您可以在这里尝试我的皮划艇原型:https://dihedral.itch.io/kayak-racing-game

2017年12月更新:此项目已重命名为Kayak Run ,现已针对iPhone和iPad发布! 在App Store上查看Kayak Run。