float delta = Mathf.Pow(velocity, 4) - gravityAcceleration * (gravityAcceleration * x * x - 2 * y * velocity * velocity); if (delta < 0) { Debug.Log("无法命中!"); return; } float theta1 = Mathf.Atan(((velocity * velocity) + Mathf.Sqrt(delta)) / (gravityAcceleration * x)); float theta2 = Mathf.Atan(((velocity * velocity) - Mathf.Sqrt(delta)) / (gravityAcceleration * x)); float angle = Mathf.Min(theta1, theta2);
注意:如果将计算出的角度直接应用到炮塔上,会发现角度并不正确,当目标明显需要仰起炮管才能命中时会看到炮管向下旋转,并不能正确命中目标。经过观察和测试,发现了问题所在。Unity中x轴的旋转,在x轴正方向上看向坐标系原点这个视野中是顺时针的,换句话说,当x轴旋转为30°时,炮管将向下旋转30°,旋转330°才是向上旋转30°。所以在处理旋转角度时,还要进行一个倒数的处理,才能让炮管转向正确的方向。由此也引导我发现了另外一个问题——抛物线所在坐标系的方向也不是我们猜想的y轴与世界坐标系y轴正方向相同,而是相反。我们带入坐标后真正计算的抛物线图像是会直接穿过地面,经过端距离再回到地面上的,与我们想要的弹道恰恰关于地平面对称。这也说明我们带入公式计算的y值,应该是一个与实际情况相反的值才能符合抛物线图像。
故在使用上述方法时,需要带入的几个值,x为炮弹起始位置到落点位置的平面距离(即在计算距离前消除水平高度差),y为炮弹落点相对炮弹起始点的海拔差的相反数,velocity为炮弹初速度,gravityAccelerate为重力加速度。这样才能真正获得准确的炮弹射出仰角。
计算出仰角再将其应用到炮管上即可。
三、过渡动画
如果炮塔设定旋转速度不快,无法跟随镜头进行目标瞄准。可以为炮塔添加一个自动旋转函数,在FixedUpdate()中调用,并使用变量,将目标的旋转角度记录下来,使用插值函数来实现炮塔的平滑旋转和瞄准,获得更好的效果。
联系客服