我尝试了以下作为运行在子弹上的脚本:
展示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;
}
}
但是,如果我在空中碰到了什么东西,它就会停止沿着弧线移动,只是自由地翻滚直到着陆。如何才能以“正确”的方式做到我想做的事情?
因为人们想要看到它,这里是生成子弹的代码。
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;
}
}
LateUpdate
用于固定计算,例如物理。您无法将基于物理的运动与变化的步骤集成在一起。您只需要知道自己在做什么。 - Adrian KrupaUpdate
中应用的飞行转向系统),并且我想要一个固定的追踪摄像机,它会平移但不会旋转(所以我不能将相机作为子对象绑定到子弹上),那么相机的逻辑应该放在LateUpdate
中,不是吗? - Scott ChamberlainLateUpdate
”,但我同意“除非更新的目标是更新相机的Translation
,否则永远不要使用LateUpdate
”。 - Scott Chamberlain