如何使弹丸转弯有弧度
How to make a projectile turn with a arc
我有一门大炮,可以沿抛物线弧线发射子弹。现在,当我发射子弹时,子弹与它从大炮中发射时保持相同的旋转。
如何才能让子弹在空中飞行时沿着弧线旋转?
我在 bullet
上尝试了以下脚本 运行
图表 1
public class PointingBehaviour:MonoBehaviour
{
private Rigidbody rb;
private void Awake()
{
rb = GetComponent<Rigidbody>();
}
public void Update()
{
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;
}
}
但如果我碰巧在空中撞到什么东西,它就会停止跟随弧线,然后自由翻滚直到落地。 "Correct" 做我想做的事情的方法是什么?
因为大家想看,这里是生成子弹的代码。
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;
}
}
我相信您所说的是 - 您的脚本 exhibit1 效果很好。
如果你考虑一下,你所要做的就是关闭该行为,当你想要的时候。
在这种情况下,您在想“该行为在落地时应该停止......我认为这就是您的物理意思。
关闭 MonoBehaviour
非常容易,正如您所知道的 enabled = false;
所以,你有一些脚本,比如 Bullet
或者 BulletBoss
在那里你会有一个变量 private PointingBehaviour pb
而你只是 pb.enabled = false
(我不能告诉你 "when" 你想这样做,这取决于你的游戏..所以它可能是 "when altitude is less than blah" 或 "when I hit something" ...可能 OnCollisionEnter
相关。)
请注意 - 我相信你知道这一点 - 对于射弹的指向行为,只需沿着切线设置它是非常基本的。
当你为像这样的射弹编写指向行为时,这是一件非常容易做的可爱的事情,试着轻轻地将它移动到切线。结果是令人惊叹的真实外观。接下来也许添加一些非常像炸弹的随机 "wiggles"。令人惊奇的是用户如何能够看到这样的东西,只有几帧。 (我猜下一步将是真正的空气物理学!)
请注意,当然,PointingBehaviour
应该只是它自己的脚本。你必须保持行为完全孤立。
关于提到的 LateUpdate
,永远 不需要使用它。
Unity 提供了一个 "script order execution" 系统(请参阅首选项菜单选项),如果您真的想在框架内进行排序。但这样做的唯一原因可能是出于某种实验原因。
这很像 "using a global" - 没有理由这样做。与任何代码一样,如果您必须按给定顺序执行某些操作,只需按顺序调用即可。
我有一门大炮,可以沿抛物线弧线发射子弹。现在,当我发射子弹时,子弹与它从大炮中发射时保持相同的旋转。
如何才能让子弹在空中飞行时沿着弧线旋转?
我在 bullet
上尝试了以下脚本 运行图表 1
public class PointingBehaviour:MonoBehaviour
{
private Rigidbody rb;
private void Awake()
{
rb = GetComponent<Rigidbody>();
}
public void Update()
{
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;
}
}
但如果我碰巧在空中撞到什么东西,它就会停止跟随弧线,然后自由翻滚直到落地。 "Correct" 做我想做的事情的方法是什么?
因为大家想看,这里是生成子弹的代码。
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;
}
}
我相信您所说的是 - 您的脚本 exhibit1 效果很好。
如果你考虑一下,你所要做的就是关闭该行为,当你想要的时候。
在这种情况下,您在想“该行为在落地时应该停止......我认为这就是您的物理意思。
关闭 MonoBehaviour
非常容易,正如您所知道的 enabled = false;
所以,你有一些脚本,比如 Bullet
或者 BulletBoss
在那里你会有一个变量 private PointingBehaviour pb
而你只是 pb.enabled = false
(我不能告诉你 "when" 你想这样做,这取决于你的游戏..所以它可能是 "when altitude is less than blah" 或 "when I hit something" ...可能 OnCollisionEnter
相关。)
请注意 - 我相信你知道这一点 - 对于射弹的指向行为,只需沿着切线设置它是非常基本的。
当你为像这样的射弹编写指向行为时,这是一件非常容易做的可爱的事情,试着轻轻地将它移动到切线。结果是令人惊叹的真实外观。接下来也许添加一些非常像炸弹的随机 "wiggles"。令人惊奇的是用户如何能够看到这样的东西,只有几帧。 (我猜下一步将是真正的空气物理学!)
请注意,当然,PointingBehaviour
应该只是它自己的脚本。你必须保持行为完全孤立。
关于提到的 LateUpdate
,永远 不需要使用它。
Unity 提供了一个 "script order execution" 系统(请参阅首选项菜单选项),如果您真的想在框架内进行排序。但这样做的唯一原因可能是出于某种实验原因。
这很像 "using a global" - 没有理由这样做。与任何代码一样,如果您必须按给定顺序执行某些操作,只需按顺序调用即可。