C# 如何使射弹以弧形转弯

C# 如何使射弹以弧形转弯,c#,unity3d,game-physics,C#,Unity3d,Game Physics,我有一门可以发射抛物线形子弹的大炮。现在,当我发射子弹时,它的旋转方向和从大炮中发射时一样 我如何使子弹在空气中旋转时沿着弧线 我试着用下面的脚本在子弹上运行 附件1 public class PointingBehaviour:MonoBehaviour { private Rigidbody rb; private void Awake() { rb = GetComponent<Rigidbody>(); } pub

我有一门可以发射抛物线形子弹的大炮。现在,当我发射子弹时,它的旋转方向和从大炮中发射时一样

我如何使子弹在空气中旋转时沿着弧线

我试着用下面的脚本在子弹上运行

附件1

public class PointingBehaviour:MonoBehaviour
{
    private Rigidbody rb;

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

    public void Update()
    {
        transform.up = rb.velocity;
    }
}
公共类指针行为:单行为
{
私人刚体;
私人空间
{
rb=GetComponent();
}
公共无效更新()
{
transform.up=rb.velocity;
}
}
而且效果相当不错。但是我在物体存在的第一帧上看到了轻微的闪烁(我想这是因为在这一点上速度仍然是0),物体一旦碰到地面就无法控制地旋转

我让它在开始时停止闪烁,在落地时停止旋转,方法如下

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;
    }
}
公共类BulletController:MonoBehavior
{
私人刚体;
私人住宅;
private bool_firstFrame;
私有void Start()
{
_rb=GetComponent();
_firstFrame=true;
_followArc=true;
}
公共更新()
{
if(_followArc&!_firstFrame)
transform.up=_rb.velocity;
_firstFrame=false;
}
公共无效OnCollisionCenter(碰撞)
{
_followArc=假;
}
}
但是,如果我碰巧在空中撞到什么东西,它就会随着弧线停止,然后自由翻滚直到它落地。做我想做的事情的“正确”方式是什么


因为人们想看,这里是产生子弹的代码

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;
    }
}
公共类TankController:MonoBehavior
{
私有变换_barrelPivot;
私有转换_bullettspawn;
公共游戏对象子弹;
公众漂浮火力;
公众浮标轮换速度;
公众浮标倾斜速度;
私有void Start()
{
_barrelPivot=GetComponentsInChildren()。首先(x=>x.CompareTag(“BarrelPivotPoint”);
_bulletSpawn=GetComponentsInChildren()。首先(x=>x.CompareTag(“bulletSpawn”);
}
私有void更新()
{
if(Input.GetKeyDown(KeyCode.Space))
{
火炮();
}
//(剪断)左右转动和上下转动的手柄。
}
私人消防炮()
{
var newBullet=spawnbillet();
var rb=newBullet.GetComponent();
rb.AddForce(_bulletSpawn.up*火力,ForceMode.pulse);
}
私有游戏对象bullet()
{
var newBullet=(游戏对象)实例化(Bullet、\u bulletSpawn.position、\u bulletSpawn.rotation);
newBullet.transform.localScale=Bullet.transform.localScale;
返回纽布利特;
}
}

我相信你的意思是——你的剧本展1非常棒

如果你想一想,你所要做的就是在你想的时候关掉这种行为

在这种情况下,你在想“当行为触地时应该停止……我想这就是你身体上的意思。”

关闭
monobhavior
非常容易,正如您所知,
enabled=false;

因此,您有一些脚本,比如
Bullet
或者
BulletBoss

在这里,您将有一个变量private
pointingbehavior pb
,您只需要pb.enabled=false

(我不能告诉你“什么时候”你想这么做,这取决于你的比赛...所以可能是“当海拔低于布拉赫”或“当我击中某物时”…可能是
OnCollisionCenter
相关。)

请注意——我相信你知道这一点——对于投射物的指向行为,沿着切线设置它是非常基本的

当你为这样一个投射物编写一个指向行为时,一件非常简单的事情是,试着轻轻地将它移动到切线上。结果是令人惊讶的真实外观。接下来可能会添加一些非常像炸弹的随机“摆动”。令人惊讶的是,用户可以看到这样的东西,只有几帧。(我想下一步将是真正的空气物理学!)

请注意,当然,
pointingbehavior
应该只是它自己的脚本。您必须将行为完全隔离


关于所提到的
LateUpdate
,永远不需要使用它

Unity提供了一个“脚本顺序执行”系统(见首选项菜单选项),如果你真的想在框架内进行排序的话。但这样做的唯一原因可能是出于某种实验原因


这相当于“使用全球"-没有理由这样做。就像任何代码一样,如果你必须按照给定的顺序做某件事,只需按顺序调用即可。

如果你用炮弹击中某件东西,它不应该爆炸吗?当你在空中击中某件东西时,你
想做什么?
你可以在
OnCollisionInter
中通过选中正在执行
CompareTag()的标记<代码> >游戏对象< /代码>你点击,然后你可以用独特的东西标记地面,这样你就可以识别它并相应地行动。我没有考虑到它可能会在空中接触的事实。嗨,史葛,很难同时问多个问题。史葛,你应该。基本上永远不要使用
LateUpdate
。绝对不要出于任何原因在这里使用它。这是Unity不应该出于任何原因提及的令人困惑的事情之一。它只适用于最不寻常的情况,即您在“系统”中乱转的情况帧问题。这里真的不酷。我会检查速度,如果射弹速度慢,将_followArc设置为false,如果速度快,将其更改为false。我只有时间在最薄弱的地方处理它。一旦我有机会尝试,我会接受,那时没有其他人发布任何其他内容。