首页 文章

Unity C#在围绕移动轴旋转的目标上射击抛射物

提问于
浏览
7

我正在开发一个3D太空游戏,其中相机处于恒定的2D(自上而下)状态 . 我能够在以给定速度移动的目标上发射速度的射弹,并且每次击中它 . 大!那么如果那个目标在父母身边有一个角速度呢?我注意到如果目标有一个旋转的父对象,我的投影不正确,因为它没有考虑角速度 .

我的初始代码是围绕以下假设构建的:

Position_target + Velocity_target * t = Position_shooter + Velocity_shooter * t + Bulletspeed * t

我认为射手是静止的(或可能是移动的)并需要发射一个恒定大小的子弹 .

我将上述内容简化为此

Delta_Position = Position_target - Position_shooter
Delta_Velocity = Velocity_target - Velocity_shooter

Delta_Position + Delta_Velocity * t = BulletSpeed * t

平方双方我得到一个二次方程式,我可以求解给定的行列式结果或零 . 这很完美 . 我返回一个t值,然后将目标的位置和当前速度投射到那个t,然后我有一个转塔脚本,以给定的角速度朝这个点旋转 . 如果炮塔说它在所有轴上观察到的点在1%以内,它会以速度射击子弹,如果目标没有改变其航向或速度,它会100%命中 .

我开始在我的船只/小行星上添加组件,这些组件是父对象的子项,就像连接到炮塔本身为目标的船只的炮塔 . 如果船围绕轴旋转(例如Y轴)并且炮塔不在x = 0且z = 0,则我的投影不再起作用 . 我认为使用r * sin(theta omega * t)作为X位置的角速度分量和使用Z位置的r * cos(θω* t)可以起作用 . Theta是当前旋转(相对于世界坐标),omega是围绕y轴的eulerAngle旋转 .

我很快就意识到这只适用于围绕y轴旋转,我不能将sin置于二次方程式中,因为我无法从中提取t因此我无法真正适当地投影 . 我尝试使用双曲线,但情况相同 . 我可以创建一个任意的t,假设t = 2,并计算对象在2秒内的位置 . 但我正在努力寻找一种方法来实现子弹速度投射 .

Position_targetparent + Velocity_targetparent * t + [ANGULAR VELOCITY COMPONENT] = Position_shooter + Velocity_shooter * t + Bulletspeed * t

Delta_Position_X + Delta_Velocity_X * t + S * t = r * sin (theta + Omegay * t)
Delta_Position_Z + Delta_Velocity_Z * t + S * t = r * cos (theta + Omegay * t)

从这里开始,我一直在不停地旋转我的车轮,试图找到一个可行的解决方案 . 我正在使用eulerAngle.y作为效果很好的欧米茄 . 最后,我只需要在空间中我需要射击的瞬间点,它是子弹速度和投影距离的乘积,然后我的炮塔瞄准脚本将照顾其余部分 .

我一直在寻找基于父母位置(旋转中心)的球面坐标系

Vector3 deltaPosition = target.transform.position - target.transform.root.position;
r = deltaPosition .magnitude;
float theta = Mathf.Acos(deltaPosition.z / r);
float phi = Mathf.Atan2(deltaPosition.y,deltaPosition.x);

float xPos = r * Mathf.Sin(theta) * Mathf.Cos(phi)
float yPos = r * Mathf.Sin(theta) * Mathf.Sin(phi)
float zPos = r * Mathf.Cos(theta)

Vector3 currentRotation = transform.root.gameObject.transform.rotation.eulerAngles * Mathf.Deg2Rad;
Vector3 angularVelocity = transform.root.gameObject.GetComponent<Rigidbody>().angularVelocity;

我可以根据这些角度计算物体的位置......但我正在努力将其转化为可以与omega * t(角速度)方法一起使用的东西 .

我想知道是否有一个更优雅的方法解决这个问题,或者是否有人可以指出我正确的方向指导我帮助我思考这个问题? Quaternions和EulerAngles我不是最好的,但我慢慢学习它们 . 也许我能用那些聪明的东西做些什么?

1 回答

  • 0

    虽然数学可能仍然很难,但我怀疑你可以通过让“目标”计算其在当地空间的未来位置来大大简化数学 . 然后让它将该位置调用其父级,让它在本地空间中计算,依此类推,直到达到世界空间 . 一旦你拥有了未来在世界空间中的位置,你就可以将你的炮塔对准那个目标 .

    例如,轨道船应该能够轻松地计算其未来轨道 . 这是椭圆的方程 . 然后,可以将该本地位置发送到其父级(行星),该父级(行星)可能也在轨道运行,并相对于自身计算该位置 . 然后行星将这个本地位置发送给它自己的父母(Star),依此类推 . 直到你到达世界空间 .

    您可以通过使子弹的行程时间保持恒定(灵活的速度)来进一步简化此数学运算,这样您就可以简化在特定时间确定未来的位置 . 根据您的游戏规模,速度的实际差异可能没有那么不同 .

    另一个想法:您可以及时“模拟”目标对象,而不是通过强力进行所有计算 . 确保影响位置的所有代码都可以与实际分开运行更新循环 . 简单地推进时钟前进,并在不实际移动它的情况下查看其未来位置 . 然后回到现在,将枪射向未来的位置 .

相关问题