- Home /
Shotgun Randdom Spread with true bullets C#
Hello I am looking for some help with making my shotgun have spread with its bullets. They spread just fine until i look up or down, then they start to shoot up to much or the left to much etc. This is my code:
public Transform Shootpoint1;
public Transform Shootpoint2;
public Transform Shootpoint3;
public Transform Shootpoint4;
public Transform Shootpoint5;
public Transform Shootpoint6;
public GameObject Bullet;
public float Bullet1RX;
public float Bullet1RY;
public float Bullet1RZ;
public float Bullet2RX;
public float Bullet2RY;
public float Bullet2RZ;
public float Bullet3RX;
public float Bullet3RY;
public float Bullet3RZ;
public float Bullet4RX;
public float Bullet4RY;
public float Bullet4RZ;
public float Bullet5RX;
public float Bullet5RY;
public float Bullet5RZ;
public float Bullet6RX;
public float Bullet6RY;
public float Bullet6RZ;
void Update ()
{
if (Input.GetMouseButtonDown(0))
{
Fire();
}
}
void Fire ()
{
Bullet1RX = Random.Range(-3, 3);
Bullet1RY = Random.Range(-3, 3);
Bullet1RZ = Random.Range(-3, 3);
Bullet2RX = Random.Range(-3, 3);
Bullet2RY = Random.Range(-3, 3);
Bullet2RZ = Random.Range(-3, 3);
Bullet3RX = Random.Range(-3, 3);
Bullet3RY = Random.Range(-3, 3);
Bullet3RZ = Random.Range(-3, 3);
Bullet4RX = Random.Range(-3, 3);
Bullet4RY = Random.Range(-3, 3);
Bullet4RZ = Random.Range(-3, 3);
Bullet5RX = Random.Range(-3, 3);
Bullet5RY = Random.Range(-3, 3);
Bullet5RZ = Random.Range(-3, 3);
Bullet6RX = Random.Range(-3, 3);
Bullet6RY = Random.Range(-3, 3);
Bullet6RZ = Random.Range(-3, 3);
GameObject Bullet1 = (GameObject)Instantiate(Bullet, Shootpoint1.position, Shootpoint1.rotation);
Bullet1.GetComponent<Transform>().Rotate(Bullet1RX, Bullet1RY, Bullet1RZ);
Bullet1.GetComponent<Rigidbody>().AddRelativeForce(Shootpoint1.forward * -1, ForceMode.Impulse);
Destroy(Bullet1, 5);
GameObject Bullet2 = (GameObject)Instantiate(Bullet, Shootpoint2.position, Shootpoint2.rotation);
Bullet2.GetComponent<Transform>().Rotate(Bullet2RX, Bullet2RY, Bullet2RZ);
Bullet2.GetComponent<Rigidbody>().AddRelativeForce(Shootpoint2.forward * -1, ForceMode.Impulse);
Destroy(Bullet2, 5);
GameObject Bullet3 = (GameObject)Instantiate(Bullet, Shootpoint3.position, Shootpoint3.rotation);
Bullet3.GetComponent<Transform>().Rotate(Bullet3RX, Bullet3RY, Bullet3RZ);
Bullet3.GetComponent<Rigidbody>().AddRelativeForce(Shootpoint3.forward * -1, ForceMode.Impulse);
Destroy(Bullet3, 5);
GameObject Bullet4 = (GameObject)Instantiate(Bullet, Shootpoint4.position, Shootpoint4.rotation);
Bullet4.GetComponent<Transform>().Rotate(Bullet4RX, Bullet4RY, Bullet4RZ);
Bullet4.GetComponent<Rigidbody>().AddRelativeForce(Shootpoint4.forward * -1, ForceMode.Impulse);
Destroy(Bullet4, 5);
GameObject Bullet5 = (GameObject)Instantiate(Bullet, Shootpoint5.position, Shootpoint5.rotation);
Bullet5.GetComponent<Transform>().Rotate(Bullet5RX, Bullet5RY, Bullet5RZ);
Bullet5.GetComponent<Rigidbody>().AddRelativeForce(Shootpoint5.forward * -1, ForceMode.Impulse);
Destroy(Bullet5, 5);
GameObject Bullet6 = (GameObject)Instantiate(Bullet, Shootpoint6.position, Shootpoint6.rotation);
Bullet6.GetComponent<Transform>().Rotate(Bullet6RX, Bullet6RY, Bullet6RZ);
Bullet6.GetComponent<Rigidbody>().AddRelativeForce(Shootpoint6.forward * -1, ForceMode.Impulse);
Destroy(Bullet6, 5);
}
It may be a little hard on the eyes so i am sorry. I have read some posts where they say to add a Lookat somewhere but i dont understand. Thanks in advance.
Bad phrasing, they still spread when i look up, just they all veer to the left or right when i look up or down
this script is extremely difficult to look at. time to learn about arrays and loops! it makes things so much easier. i took a $$anonymous$$ute to re write what you have with arrays. this is untested but this small amount of code should do the EXACT same thing without writing all that stuff out!
int i;
int i2;
GameObject g;
public GameObject Bullet;
Transform[] shootpoints;
float[] rots;
void Start () {
shootpoints = new Transform[6];
rots = new float[18];
i = rots.Length;
while (i>0) {i--;
rots[i]=UnityEngine.Random.Range(-3.0f,3.0f);
}
//name your shootpoints in the inspector as "shootpoint0","shootpoint1", ect..
//first is allways 0 never start with 1
i = shootpoints.Length;
while(i>0){i--;
shootpoints[i]=GameObject.Find("shootpoint"+i).transform;
}}
void Fire () {
i = 6;
while (i>0) {i--;
i2=i*3;
g = (GameObject)Instantiate(Bullet, shootpoints[i].position,shootpoints[i].rotation);
g.transform.Rotate(rots[i2],rots[i2+1],rots[i2+3]);
g.rigidbody.AddRelativeForce(shootpoints[i].forward * -1, Force$$anonymous$$ode.Impulse);
Destroy(g, 5);
}}
as far as the behavior its a bit difficult for anyone to answer with out seeing your game. you simply need to keep adjusting to you get it right. but this way you only have to write it once ins$$anonymous$$d of six times. and can change your random amount in one line ins$$anonymous$$d of writing it 16 times! hopefully this makes things easier.
Thanks for the response, I added your script and edited it a little. $$anonymous$$uch easier to look at now! Going to remake the actual shoot points and see if that fixes the problem of it shooting in the wrong direction when looking up or down which it still does.
Answer by Rosh7X · Apr 09, 2017 at 10:56 PM
After more testing I changed the code around to change Shoot Points rotation instead of the bullets and used AddForce instead of AddRelativeForce.
void Fire()
{
rots = new float[18];
i = rots.Length;
while (i > 0)
{
i--;
rots[i] = UnityEngine.Random.Range(-3.0f, 3.0f);
}
i = 6;
while (i > 0)
{
i--;
i2 = i * 3;
shootpoints[i].transform.Rotate(rots[i2], rots[i2 + 1], rots[i2 + 2]);
g = (GameObject)Instantiate(Bullet, shootpoints[i].position, shootpoints[i].rotation);
g.GetComponent<Rigidbody>().AddForce(shootpoints[i].forward * 10, ForceMode.Impulse);
Destroy(g, 5);
shootpoints[i].transform.Rotate(-rots[i2], -rots[i2 + 1], -rots[i2 + 2]);
}
}
I'm glad you you got it! one other thing. It's generally bad practice to continuously spawn and destroy large amounts of game objects. When objects are Destroyed, There is something that runs in the background called "garbage collection" that needs to clean up the scene and reconfigure the empty memory space. GC can cause poor performance or affect smooth movement. For this reason its common practice to recycle bullets bullets ins$$anonymous$$d of destroying them.
In your case you would keep using the same bullets and just snap the their positions back to the gun every time they are fired. if your player can fire shots quickly you might need 2 sets to rotate through but it would still be better than GC issues. many programmers even argue that Instantiate itself if is not good for preformance during runtime.
Answer by James2Games · Jan 27, 2019 at 08:10 AM
For other people looking for a similar script but for 2D (Can be changed to work for 3D games)
This will fire x amount of bullets in a range of degrees starting from the rotation of the GameObject.
public int BulletsShot; // Total bullets show per Shot of the gun
public float BulletsSpread; // Degrees (0-360) to spread the Bullets
public Bullet BulletTemplate; // Bullet to fire
public void Fire()
{
float TotalSpread = BulletsSpread / BulletsShot;
for (int i = 0; i < BulletsShot; i++)
{
// Calculate angle of this bullet
float spreadA = TotalSpread * (i+1);
float spreadB = BulletsSpread / 2.0f;
float spread = spreadB - spreadA + TotalSpread / 2;
float angle = transform.eulerAngles.y;
// Create rotation of bullet
Quaternion rotation = Quaternion.Euler(new Vector3(0, spread + angle, 0));
// Create bullet
Bullet bullet = Instantiate(BulletTemplate);
bullet.transform.position = transform.position;
bullet.transform.rotation = rotation;
}
}