最近用了将近半个多月的时间研究如何用unity制作赛车游戏,找了搜索了网上很多的资料,哔哩哔哩上也看了很多视频,发现有用的资料少的要死,大多数都是为了赚眼球弄得垃圾demo,毫无可玩性(简直就是垃圾),也读了unity官方的赛车游戏和飞行游戏的demo,发现可以借鉴的地方少的要死(具体为什么下面会提到),下面的关于如何制作一个稳定的赛车游戏的总结:
我
这里提出几个有用的问题,我将根据问题去逐一解决。
1.我要制作一个怎样的赛车游戏:
狂野飙车是不可能的,如果牛顿知道有这么一款反重力游戏,估计会高兴的从棺材里爬起来玩个三天三夜。
由于是第一次做赛车游戏,所以这里我决定做一个模拟赛车游戏,前进键前进,后退键后退,左右键打方向,空格键手刹,shift键是脚刹。
2.如何去构建赛车的基本结构:
这里懒得写,直接操unity官方的结构构建一个。
3.赛车的基本控制代码如何编写:
这里懒得写,网上一大堆,就是那几个代码,驱动扭矩力,制动扭矩力,四驱,前后驱。
4.赛车轮子的参数如何设置:
这里估计很多开发者刚接触的时候会发现,车子总是会莫名其妙的弹起来,启动会左右摇摆。弹起来的因为你的车子轮子的回复力已经超过了承受的重力 ,根据摩擦系数跟摩擦力和重力之间的关系,摩擦力是小于重力的,修改参数吧,至于轮子的参数,尤其是纵向摩擦和横向摩擦,建议先去看看官方这方面的内容搞清楚了再来看下面的内容。
5.赛车如何防止侧翻:
这里我们使用一些辅助性物理的方式的处理:
第一种,设置较低的重心,就是设置rigidbody的质量中心在车子较低的位置。
第二种:添加额外辅助压力,这里参考官方代码,由于这里是反物理辅助性的,不要使用太大,如果你要绝对的仿真,那么就最好不用,不过玩家哪管这些呢。
m_WheelColliders[0].attachedRigidbody.AddForce(-transform.up * m_Downforce *m_WheelColliders[0].attachedRigidbody.velocity.magnitude);
第三种:平衡杆系统,这里具体内容贴上一个大佬的地址。
平衡杆系统对赛车游戏可以说具有很大的效用,对防止侧滑也是起到很大的作用。
var WheelL : WheelCollider;
var WheelR : WheelCollider;
var AntiRoll = 5000.0;
function FixedUpdate ()
{
var hit : WheelHit;
var travelL = 1.0;
var travelR = 1.0;
//计算两侧轮胎在不同情况下的悬挂系数
var groundedL = WheelL.GetGroundHit(hit);
if (groundedL)
travelL = (-WheelL.transform.InverseTransformPoint(hit.point).y - WheelL.radius) / WheelL.suspensionDistance;
var groundedR = WheelR.GetGroundHit(hit);
if (groundedR)
travelR = (-WheelR.transform.InverseTransformPoint(hit.point).y - WheelR.radius) / WheelR.suspensionDistance;
//计算平衡杆刚度系数
var antiRollForce = (travelL - travelR) * AntiRoll;
//向两侧的轮胎分配力
if (groundedL)
rigidbody.AddForceAtPosition(WheelL.transform.up * -antiRollForce, WheelL.transform.position);
if (groundedR)
rigidbody.AddForceAtPosition(WheelR.transform.up * antiRollForce, WheelR.transform.position);
}
6.赛车如何防止侧滑:
这里估计是所有刚接触的开发者遇到的最大问题了,开开心心敲代码,已启动车子,刺溜就滑着去了,转弯吃力,刹车刹不了,一头的无力感。其实这也是个很鸡肋的问题。由于unity的物理引擎是进行的真实物理模拟,如果我们把这里的侧滑摩擦系数调到尽量高,会发现还是会打滑,而现实中你把车子开到这个速度,也会打滑,侧翻也会比这个严重,只是现实中车子的速度都比较慢,启动转弯等都是缓慢过度的,所以感觉不出来。
上面防止侧翻的额外添加的力其实无形中也增加了摩擦力,但是作用不明显;至于平衡杆带来的防止侧滑的效果我暂时没有研究出来。所以我们可以添加一些额外辅助的效果力,虽然有些反物理,但是玩的爽就行了。根据获取每个轮子的侧滑值,在每个轮子处添加与该轮子侧滑方向相反的力(乘以侧滑值,获取的侧滑值变量限定在0到1之间),这里相当于额外增加了侧向摩檫力,从而增加了防止摩擦打滑的效果。然而我们感觉一些模拟游戏中侧滑不严重,是因为开发者对赛道做了侧向高低处理,所以游戏的时候侧滑就会被抵消掉一部分,无形中增加了游戏体验(这里我做了个实验,把一个赛车游戏的车子demo放到平地实验,妹的打滑情况比我的游戏车子还严重)。
这里呢,由于游戏中漂移主要来自一定的侧滑,但是侧滑严重又会导致游戏体验糟糕,所以这里比较考研开发者的耐心。
7.关于赛车以及漂移和氮气的那些事:
现实中,只开过摩托车,所以呢查了一下,漂移就是用足够的速度和手刹来实现。但是游戏中一点小速度就可以漂移(太假了)。氮气在游戏中简直就是科幻的存在,就好像车子突然装了一个火箭发动机。然而,真实的情况是氮气瓶其实就是用于提高发动机引擎的加速度,换句话说平时一点卵用没有,该翻车还是得翻车。另外呢上面提到的只是小游戏中的开发,如果是大型游戏,像geta5那样,估计一个车子的外设参数能有上百个,估计除了这个车子的程序员,没人能看的清楚,所以游戏贵也是有道理的。这里要吐槽一下unity官方的赛车游戏代码,我一直很纳闷官方是如何解决侧向打滑和拐弯的,然后一个代码SteerHelper(),看了这段狗屎一样的代码让人崩溃,这是强行改变车子的速度方向,带来的副作用就是你拐弯的时候会严重的拐弯,将一个糟糕的体验转换成另一个糟糕的体验,这样的有意义吗。
8.车子如何限速:
关于车子的限速,unity官方里面还是老方法,直接用数学限速,但是这里没有考虑到车子方向与速度方向的问题,甚至车子在空中也会被限速。这里我们有三个限速方案,前两个时物理限速,第三个是数学限速。
第一种:取得速度在轮子方向的分量Vf,求出Vf与限定速度的分量绝对值比例b,限定b在0到1之间,用1-b求得力矩比例bf,bf乘以力矩,就得到轮子上所施加的力矩量 。这里解释一下,相当于我们车子速度足够快的时候,轮子的速度已经到达了扭矩轴所能达到的最高速度,也就是说扭矩轴不能再对该轮子施加速度加持了。用这个方法有个好处,就是车子在下坡等某些情况下可以超过最高速度。但是就真实情况而言,即使是下坡速度也是被挡位齿轮限制住的,所以暂时讨论到此(还没做完)。
第二种:同样取得分量比例,但是这次不用力矩分量,而是使用刹车分量,即增加一个限速刹车分量,当速度分量超过最大速度时,通过限速刹车分量对车子进行刹车控制,从而起到挡位齿轮控制车速的作用。
第三种:先判断轮子是否在地面上(在控制坠落的车子无法限速),如果有,那么限制车子在车子前方分量的速度值。但是这样做的弊端就是车子在被其他车子撞到的时候,在该方向上的速度也不会增加