Search code examples
unity-game-enginephysicsprojectile

Tips for improving the look of projectiles in Unity


Is there some better way of instantiating simple projectiles in Unity so that they look better (esp while moving). Currently, it looks like this for me (blue marks player's move direction, yellow marks direction I'm firing in).

enter image description here

My fire rate and the bullet's speed is set quite high, but as best as I can tell, I believe there's some delay from when the bullet is created, before it actually accelerates to the intended speed? Just a few frames, but more than enough to make it look weird.

With more bullets etc, naturally it looks even stranger.

Here is the code I use to fire these bullets:

public class RangedWeapon : Weapon
{
    [Header("General")]
    [SerializeField] protected Transform firePoint;
    [SerializeField] protected Projectile projectile;

    protected override void HandleFire()
    {
        Projectile proj = Instantiate(projectile, firePoint.position, firePoint.rotation);
        proj.Fire(firePoint.forward);
    }
}

public class Projectile : MonoBehaviour
{
    [SerializeField] protected float speed;
    [SerializeField] protected float lifeTime;
    protected Rigidbody rbody;
    protected float timer;

    protected void Awake()
    {
        rbody = GetComponent<Rigidbody>();
    }

    public void Fire(Vector3 dir)
    {
        transform.forward = dir;
        rbody.velocity = transform.forward * speed;
    }
}

A debug of the speed of the projectile's speed after a single shot shows the following via the code

    protected void Update()
    {
        timer += Time.deltaTime;
        Debug.Log($"CurrentSpeed: {rbody.velocity.magnitude}");
        if (timer >= lifeTime)
        {
            DestroyProjectile();
        }
    }

enter image description here

So as you can see, there is a single Update call where the speed is 0 (presumably when the object is first created). What I need is to be able to "prewarm" the object or something.


Solution

  • The problem is because you fire the bullet on Update but velocity only kicks in once Unity reaches the nearest by FixedUpdate. You can fix this by remembering on Update that you need to fire a bullet, but only actually firing it on FixedUpdate.