如何用弧形制造抛射物

时间:2016-02-02 18:37:16

标签: c# unity3d game-physics

我有一门用抛物线射出子弹的大炮。现在,当我开火时,子弹保持与从大炮射出时相同的旋转。

animation

如何使子弹的旋转跟随弧线传播到空中?

我尝试了以下作为在子弹上运行的脚本

图表1

public class PointingBehaviour:MonoBehaviour
{
    private Rigidbody rb;

    private void Awake()
    {
        rb = GetComponent<Rigidbody>();
    }

    public void Update()
    {
        transform.up = rb.velocity;
    }
}

这很有效。但是我看到物体存在的第一帧有轻微的闪烁(我认为这是因为此时速度仍为0)并且物体一旦撞到地面就会无法控制地旋转。

animation

我让它在开始时停止闪烁,并通过执行以下操作停止旋转

public class BulletController : MonoBehaviour
{
    private Rigidbody _rb;
    private bool _followArc;
    private bool _firstFrame;
    private void Start()
    {
        _rb = GetComponent<Rigidbody>();
        _firstFrame = true;
        _followArc = true;
    }

    public void LateUpdate()
    {
        if (_followArc && !_firstFrame)
            transform.up = _rb.velocity;
        _firstFrame = false;
    }

    public void OnCollisionEnter(Collision collision)
    {
        _followArc = false;
    }
}

但是,如果我碰巧撞到空中的东西,它会在弧线后停下来,只是自由翻滚直到落地。什么是“正确”的方式来做我想做的事情?

因为人们想看到它,所以这里是产生子弹的代码。

public class TankController : MonoBehaviour
{

    private Transform _barrelPivot;
    private Transform _bulletSpawn;
    public GameObject Bullet;
    public float FirePower;
    public float RotationSpeed;
    public float TiltSpeed;

    private void Start()
    {
        _barrelPivot = GetComponentsInChildren<Transform>().First(x => x.CompareTag("BarrelPivotPoint"));
        _bulletSpawn = GetComponentsInChildren<Transform>().First(x => x.CompareTag("BulletSpawn"));
    }

    private void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            FireCannon();
        }
        //(SNIP) Handle turning left and right and pivoting up and down.
    }

    private void FireCannon()
    {
        var newBullet = SpawnBullet();
        var rb = newBullet.GetComponent<Rigidbody>();
        rb.AddForce(_bulletSpawn.up * FirePower, ForceMode.Impulse);
    }

    private GameObject SpawnBullet()
    {
        var newBullet = (GameObject) Instantiate(Bullet, _bulletSpawn.position, _bulletSpawn.rotation);
        newBullet.transform.localScale = Bullet.transform.localScale;
        return newBullet;
    }
}

1 个答案:

答案 0 :(得分:2)

我相信你所说的是 - 你的脚本展览1很有效。

如果您考虑一下,您只需关闭该行为即可。

在这种情况下,你会思考&#34;这种行为应该在它触地时停止。我认为这就是你的意思。

很容易关闭MonoBehaviour,正如您所知enabled = false;

所以,你有一些脚本,如BulletBulletBoss

在那里,您将拥有一个变量私有PointingBehaviour pb,而您只是pb.enabled = false

(我不能告诉你&#34;当&#34;你想要这样做,这取决于你的游戏......所以它可能类似于&#34;当海拔低于等等时#&#34; 34;或者&#34;当我点击某些东西&#34; ...可能OnCollisionEnter相关。)

请注意 - 我确定你知道这一点 - 对于射弹的指向行为,只需沿着切线设置就非常基本。

当你为这样的抛射物写出指向行为时,可以做一件非常容易的事情,试着轻轻地将它轻轻地拉到切线上。结果是惊人的真实外观。接下来可能会添加一些随机的&#34; wiggles&#34;这是非常炸弹般的。令人惊讶的是用户如何看到这样的东西,只有几帧。 (我想下一步将是真实的空气物理学!)

请注意,当然,PointingBehaviour应该只是它自己的脚本。你必须保持行为完全孤立。

关于提到的LateUpdate从不需要使用它。

Unity提供&#34;脚本订单执行&#34;系统(参见“首选项”菜单选项),如果真的想在框架内订购。但关于这样做的唯一原因可能是出于某些实验原因。

它更像是&#34;使用全球&#34; - 没有理由。与任何代码一样,如果您必须按给定顺序执行某些操作,请按顺序调用。