How do I create a bullet spread from this code?

I want to create bullet spread for my game I am currently working on. I tried following one tutorial, but it didn’t work.
The way bullets work on my game is they are always raycasted in the middle of the screen from an empty game object and I want to create random bullet spread from that game object, but the question is how do I do it?

private void Fire(){
        if (firetimer < firerate || CurrentBullets <= 0 || IsReload )
            return;
       
        RaycastHit hit;


        if (Physics.Raycast (ShootPoint.position, ShootPoint.forward, out hit, range)) {
            Debug.Log (hit.transform.name + "found");

       
            GameObject hitParticlesEffect = Instantiate (HitParticles, hit.point, Quaternion.FromToRotation (Vector3.up, hit.normal));
            hitParticlesEffect.transform.SetParent (hit.transform);
            //Spawning both hit particles and bullet holes and setting their parents to whatever the ray cast hit
            GameObject BulletObjectEffect = Instantiate (BulletObject, hit.point, Quaternion.FromToRotation (Vector3.forward, hit.normal));
            BulletObjectEffect.transform.SetParent (hit.transform);


            Destroy (BulletObjectEffect, 2f);
            Destroy (hitParticlesEffect, 1f);

            if (hit.transform.GetComponent<EnemyHealth> ()) {
                hit.transform.GetComponent<EnemyHealth> ().ApplyDamage (damage + ArmorPenetration);
            }
        }

Sorry, don’t have exact code to give you (not at my home/Unity PC, and also it might need to be slimmed down a bit), but I can give you an idea as to what I personally did. This might be a little overly convoluted, so you may slim this down.

I have a function that just shoots out a bullet. It accepted a float parameter (you might do a quaternion, or something else) to indicate the angle of the shot from the gun tip. I called this my offset. I used a float just because I only needed to work on the Y axis for rotation. This aforementioned shoot function will get called multiple times by my “spread” function.

I had a few variables set up for this:

  • a transform I called “bulletSpawn” (where the bullet shoots out of… i.e. tip of the
  • bulletCount (how many bullets in my spread)
  • bulletSeparationAngle (the degree difference between each bullet).
  • a variable to indicate my left y rotation through the spread, and one for the right rotation through the spread. This number shifts along as bullets are shot… basically to increase the offset in either direction for the next bullet.

I had a counter to indicate the number of bullets remaining, and that counts down as each call to my bullet shooting function is made.

I first checked if the bullet count was odd or even. If it’s odd, your shooting a bullet right down the middle (0 degrees offset). If it was even, you split your bulletSeparationAngle in half, and you’ve got one bullet with a negative offset of that half amount, and another shooting with the positive offset. So now you’ve figured out the initial middle part of the spread, now it’s just a matter of adding on your bulletSeparationAngle to your left and right rotations for each bullet.

For that, I divided my remaining bullet count in half, then I just did all the left bullets in a for loop… for i, … i less than number of bullets remaining in the left side, kinda thing… leftYRotation -= bulletSeparationAngle… then call my bullet shooting function passing leftYRotation… then reduce the number of bullets in the left side… … when all done, on to the right side.

Sorry, it’s probably a lot harder to explain than it is to do. I hope this helps. If you can take a stab at this, I can (or someone else can) walk you through problems. Someone else might also have a much more slick idea, but this way worked well for me.

Oh, and the function for shooting a bullet that I repeatedly call looked something like this:

targetRotation.eulerAngles = new Vector3(0.0f, bulletSpawn.transform.eulerAngles.y + offset, 0.0f);

Edit: Sorry, forgot to mention, the bullets themselves do the raycasting to see if they hit anything.

So basically somewhere along the lines of this:

Vector3 direction = ShootPoint.forward; // Bullet Spread
        float currentSpread = Mathf.Lerp(normalSpread,maxSpread,firerate/TimeTillNextSpread);
        direction.x += Random.Range(-currentSpread, currentSpread);
        direction.y += Random.Range(-currentSpread, currentSpread);
        direction.z += Random.Range(-currentSpread, currentSpread);

It works and I don’t feel like the bullet counting is necessary unless we are talking about a shotgun. However, for an automatic or a semi-automatic gun well that feels a little bit uncalled for.

Oh, the idea I described above was used specifically for a shotgun blast in my game, and I just wanted a consistent spread. Wasn’t sure what your use case was.