Stop creating and destroying every bullet.

Reuse them. Unity has a pool built in.

Stop creating and destroying every bullet.

The problem

New every shot, gone every hit.

void Fire(){    var b = Instantiate( bulletPrefab );} // in Bullet.cs, on hitDestroy( gameObject );

Instantiate and Destroy are expensive, and the garbage they leave causes stutters.

The fix

Borrow it. Give it back.

A pool keeps finished bullets switched off, and hands them out again instead of making new ones.

Get()→use→Release()

The fix in code

UnityEngine.Pool.

ObjectPool<Bullet> _pool; void Awake(){    _pool = new ObjectPool<Bullet>(        () => Instantiate( bulletPrefab ),        b => b.gameObject.SetActive( true ),        b => b.gameObject.SetActive( false ) );} void Fire() => _pool.Get();

Tell it how to create, take and return a bullet. Get hands one out, making a new one only if none are free.

On hit

Release, don't Destroy.

// Bullet needs a reference back to its poolvoid OnHit(){    pool.Release( this );}

Release switches it off and puts it back for the next shot.

The rule

Spawn a lot? Pool it.

Take one
pool.Get()
Done with it
pool.Release( b )
Destroy
never, for pooled objects