Right now, when shooting my gun, I’m using if (Physics.Raycast(shotOrigin.position, shotOrigin.forward, out hit, 1000, layerMask))but I want to add a slight random variation so the bullet isn’t always shooting perfectly forward in exactly the same place each time (I want little bit of up/down and left/right variety), and I just can’t figure out the correct way to write any code to do this.
You could first create your spread effect in world space.
Create a vector forward in world space, which has some offset in it’s x and y:
Vector3 dir = new Vector3(Random.Range(-offset,offset),Random.Range(-offset,offset),1f);
When you have this, this should be transformed from the “drawing board” to something useful, i.e. to your objects local space (= weapon’s tip or whatever).
@Bunny83 has listed plenty of alternatives for this kind of scenarios here:
Here is a slightly inelegant but easy way to implement some bullet spread.
//This variable should probably be public, so that you easily can change it. It should probably also be pretty small
float maxSpread = 0.2f;
//We calculate the shots divergence from the original trajectory and put it into a vector.
float xSpread = Random.RandomRange(-maxSpread, maxSpread);
float ySpread = Random.RandomRange(-maxSpread, maxSpread);
float zSpread = Random.RandomRange(-maxSpread, maxSpread);
Vector3 spreadVector = new Vector3(xSpread, ySpread, zSpread);
//Here we combine the spread with the shooting direction and normalize it, so that it has the length/magnitude 1.
Vector3 shootingDirection = (spreadVector + shotOrigin.forward).normalized;
//Then you just call your original raycast like this
Physics.Raycast(shotOrigin.position, shootingDirection, out hit, 1000, layerMask)
public static Vector3 GetPointOnUnitSphereCap(Quaternion targetDirection, float angle)
{
var angleInRad = Random.Range(0.0f,angle) * Mathf.Deg2Rad;
var PointOnCircle = (Random.insideUnitCircle.normalized)*Mathf.Sin(angleInRad);
var V = Vector3(PointOnCircle.x,PointOnCircle.y,Mathf.Cos(angleInRad));
return targetDirection*V;
}
public static Vector3 GetPointOnUnitSphereCap(Vector3 targetDirection, float angle)
{
return GetPointOnUnitSphereCap(Quaternion.LookRotation(targetDirection), angle);
}
Instead of shotOrigin.forward you can use
GetPointOnUnitSphereCap(shotOrigin.forward, 5)
which returns a vector in the same direction as “shotOrigin.forward” but with a random variance of 5° Note that a value of 180° would mean you get a completely random direction. So keep in mind that the cone angle is twice the angle- So if you pass 45 as angle the cone would have a 90° angle at the tip.