So I made a shotgun script...but something's not right. Could use some help thanks.

Something weird is going on where it seems like the spread varies based on where my camera turns. What basically happens is that if I turn left roughly 90 degrees, all of the pellets will stack on top of each other for the duration of their flight, or there will be very minimal spread. As I look up, the spread will build larger.

If I turn right roughly 90 degrees the spread becomes gigantic. Basically I’m not sure why this is occurring. I’ve found one other person that reported this same problem, but nobody responded to it. Thanks.

#pragma strict

public class Shotgun extends Weapon {
	var weaponDurability : int;
	var minDamage : float;
	var maxDamage : float;
	var rateOfFire : int;
	var pelletCount : int;
	var spreadFactor : float;
	
	var bullet : Transform;
	
	function AttackPrimary(x : float){
		if(x >= 1.0 / (rateOfFire / 60)) {
			var pellet : Transform;

			for(var i = 0; i < pelletCount; i++){
				var pelletRot = Camera.main.transform.rotation;
				pelletRot.x += Random.Range(-spreadFactor, spreadFactor);
				pelletRot.y += Random.Range(-spreadFactor, spreadFactor);
				pellet = Instantiate(bullet, Camera.main.transform.position, Camera.main.transform.rotation);
				pellet.transform.rotation = pelletRot;
				pellet.GetComponent(BulletScript).damage = Random.Range(minDamage, maxDamage);
				pellet.rigidbody.AddForce(pellet.transform.forward * 300);
			}
			transform.parent.gameObject.SendMessage("ResetWeaponTimer");
		}
	}
	function AttackSecondary() {
		print("Aim");
	}	
}

You’re adding a force to the pellets based on the rotation.
You’re setting the roration based on the spread factor.
I can’t see where you’re setting the spread factor, but it doesn’t seem to be based on camera angle.
Perhaps if you added the spreadfactor rotation to the current rotation instead of replacing it, you will get more consistent results.

Another thing that might be happening here is that your pellets are all colliding with eachother since they are spawned at the same location. The physics engine might be screwing with the pellets in order to resolve the collision problems it has. Make sure that the pellets are in a layer that doesn’t collide with itself, or spawn the pellets in such a way they don’t initially collide with eachother.

var pelletRot = Camera.main.transform.rotation;
 pelletRot.x += Random.Range(-spreadFactor, spreadFactor);
pelletRot.y += Random.Range(-spreadFactor, spreadFactor);
pellet = Instantiate(bullet, Camera.main.transform.position, Camera.main.transform.rotation);
pellet.transform.rotation = pelletRot;
pellet.rigidbody.AddForce(pellet.transform.forward * 300);

Shouldn’t this-

  1. set pelletRot to rotation of camera
  2. rotate pelletRot on x and y by a random value between -spreadFactor and +spreadFactor (atm spreadFactor is set to .03)
  3. Instantiate bullet prefab with camera position and rotation (I have collider on bullet turned off so collision is not causing it)
  4. set bullet rotation to pelletRot
  5. AddForce to the pellet launching is “forward” or towards whatever direction it is rotated.

I see no reason why left and right rotation of the camera (and up/down) would add varying degrees of spread.

This I will have to try, but I’ll have to wait till I get home from work

The colliders on the bullet prefab are turned off. I would think that if there was a collision problem then it would occur regardless of where my camera faces and would launch pellets all over randomly.

Ahh…could it be that I am adding spread based on the global rotation and need to add some z rotation as well to account for aim directions that instead use z and y axis?..

You’re absolutely correct. I must have missed that part (I’m not too used to reading Java script). However after taking a second look at it, I think I see the problem.

Rotation is actually a quaternion. Setting the x and y values yourself probably won’t get you the results you’re expecting here.

try changing
var pelletRot = Camera.main.transform.rotation;
into
var pelletRot = Camera.main.transform.rotation.eulerAngles;

and

pellet.transform.rotation = pelletRot;
into
pellet.transform.rotation = Quaternion.Euler(pelletRot);

Haha I hate HATE when I come up with a possible solution at 9 am (at work) and then realize that I have to wait till 6pm to actually test it out -_-

Thanks fort he help. I need to learn about Quarternion a bit. Reading reference now, but could you explain it briefly?

Well, the most important thing you need to know is that its allmost never neded to work with Quaternions yourself in Unity. Unity offers a lot of help either setting rotations through specific rotation methods, or converting to and from euler angles (a more understandable way of setting rotations).

I wish I could help you more, but unfortunately I only know how to use rotations in Unity. I’m by no means capable enough to teach people about how quaternions work.

I wish I could say that the changes worked…but now all pellets just shoot out stacked on top of eachother as if they were one pellet.

Check how I do it in my shotgun script in my sig

function AttackPrimary(x : float) {
		if(x >= 1.0 / (rateOfFire / 60)) {
			print(x);
			var pellet : Transform;			
			for(var i = 0; i < pelletCount; i++){
				pellet = Instantiate(bullet, Camera.main.transform.position, Camera.main.transform.rotation);
				pellet.transform.Rotate(Random.Range(-spreadFactor,spreadFactor) , Random.Range(-spreadFactor,spreadFactor),0);
				pellet.rigidbody.AddForce(pellet.transform.forward * 300);
			}
			transform.parent.gameObject.SendMessage("ResetWeaponTimer");
		}
	}

changed it to this…working great now.