【问题标题】:Projectile Not Correctly Inheriting Parent Velocity (Unity3D)弹丸未正确继承父速度(Unity3D)
【发布时间】:2018-08-16 14:25:11
【问题描述】:

我正在尝试从高速移动的玩家身上发射弹丸。问题是子弹似乎没有继承角速度。如果玩家以 500 U/s 的速度直线移动,那么子弹正确地继承了该速度并将其自身的速度添加到该速度:

GameObject bullet = Instantiate(projectile, gun.transform.position, gun.transform.rotation);
bullet.GetComponent<Rigidbody>().velocity = r.velocity + bullet.transform.forward *bulletSpeed;

但是,如果玩家转得非常快,它不会继承旋转速度,并且子弹看起来会偏向一边。

我该如何实现呢?我尝试将玩家的角速度分配给子弹,但这只会导致子弹在向同一方向移动时旋转。

一些额外的细节:

  • 我正在使用rigidbody.MoveRotation() 来旋转我的播放器,但我手动计算了angularVelocity 以将其分配给子弹

  • 我尝试使用 AddTorque() 移动播放器,但无法使用子弹产生任何结果

【问题讨论】:

  • 如果您将子弹定义为枪的子对象,那么如果枪移动和/或旋转,那么子弹也将相对于枪移动。我认为这不是一个好主意。

标签: c# unity3d game-physics


【解决方案1】:

直接的问题是,直到您创建并发射射弹时,射弹才成为物理模拟的一部分,这意味着玩家在该点之前的旋转将无法影响其运动。我想如果你在开始时创建射弹,用弱关节将它连接到枪上,然后在发射时破坏关节并增加它的速度,这可能会起作用 - 但如果你只是“假装”它真的会更简单它。

应用圆周运动

这类似于物理教科书中的经典圆周运动示例。当你的子弹在玩家周围(枪内)绕一圈行进时,它的正常路径(如果释放)将与玩家周围的圆形路径相切。因此,当子弹被发射(并因此从圆形路径中释放)时,玩家的角速度将转化为子弹的线速度。这是我拼凑的一个简单图表,它代表了一个球在绳子上并绕圈旋转的情况:

获取子弹的切向速度

您不想在射弹发射后对其施加任何类型的角速度 - 正如您所看到的,这只会使射弹沿自己的轴旋转。相反,您希望对射弹应用一个额外的速度矢量,该矢量与玩家的旋转相切(并且垂直于子弹的朝向)。那么我们该怎么做呢?

嗯,根据this website,圆周旋转的物体上任意点的切向速度公式是:

速度 = 角度速度 x 半径

要记住的关键点是 angularVelocity 的单位是弧度,而不是度数。

所以,让我们把这一切放在一起。以下是您如何编写代码的大致思路:

FireGun() {
    // Assumes the current class has access to the rotation rate of the player
    float bulletAngularVelocityRad = Mathf.Deg2Rad(rotationRateDegrees)

    // The radius of the circular motion is the distance between the bullet
    // spawn point and the player's axis of rotation
    float bulletRotationRadius =
        (r.transform.position - gun.transform.position).magnitude;

    GameObject bullet =
        Instantiate(projectile, gun.transform.position, gun.transform.rotation);

    // You may need to reverse the sign here, since bullet.transform.right
    // may be opposite of the rotation
    Vector3 bulletTangentialVelocity =
        bulletAngularVelocityRad * bulletRotationRadius * bullet.transform.right;

    // Now we can just add on bulletTangentialVelocity as a component
    // vector to the velocity
    bullet.GetComponent<Rigidbody>().velocity =
        r.velocity + bullet.transform.forward * bulletSpeed + bulletTangentialVelocity;
}

希望这会有所帮助!当您使用游戏物理时,阅读一些基本的运动学/力学绝不是一个坏主意,因为有时依赖游戏物理实际上比设计自己的解决方案更复杂。

【讨论】:

  • 这是一个很好的答案。我还发现将生成点处的角速度的角度乘以玩家的旋转效果很好,这两种解决方案都是相似的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多