Bullet Spray

How would i add a range of bullet spray like in halo, when your using the assault rifle, the bullets go in a sprayed area instead of a strait line… And it would help if you could use this code as its my main shooting script from fps tutorial.

var range = 100.0;
var fireRate = 0.05;
var force = 10.0;
var damage = 5.0;
var bulletsPerClip = 40;
var clips = 20;
var reloadTime = 0.5;
private var hitParticles : ParticleEmitter;
var muzzleFlash : Renderer;

private var bulletsLeft : int = 0;
private var nextFireTime = 0.0;
private var m_LastFrameShot = -1;

function Start () {
	hitParticles = GetComponentInChildren(ParticleEmitter);
	
	// We don't want to emit particles all the time, only when we hit something.
	if (hitParticles)
		hitParticles.emit = false;
	bulletsLeft = bulletsPerClip;
}

function LateUpdate() {
	if (muzzleFlash) {
		// We shot this frame, enable the muzzle flash
		if (m_LastFrameShot == Time.frameCount) {
			muzzleFlash.transform.localRotation = Quaternion.AngleAxis(Random.value * 360, Vector3.forward);
			muzzleFlash.enabled = true;

			if (audio) {
				if (!audio.isPlaying)
					audio.Play();
				audio.loop = true;
			}
		} else {
		// We didn't, disable the muzzle flash
			muzzleFlash.enabled = false;
			enabled = false;
			
			// Play sound
			if (audio)
			{
				audio.loop = false;
			}
		}
	}
}

function Fire () {
	if (bulletsLeft == 0)
		return;
	
	// If there is more than one bullet between the last and this frame
	// Reset the nextFireTime
	if (Time.time - fireRate > nextFireTime)
		nextFireTime = Time.time - Time.deltaTime;
	
	// Keep firing until we used up the fire time
	while( nextFireTime < Time.time  bulletsLeft != 0) {
		FireOneShot();
		nextFireTime += fireRate;
	}
}

function FireOneShot () {
	var direction = transform.TransformDirection(Vector3.forward);
	var hit : RaycastHit;
	
	// Did we hit anything?
	if (Physics.Raycast (transform.position, direction, hit, range)) {
		// Apply a force to the rigidbody we hit
		if (hit.rigidbody)
			hit.rigidbody.AddForceAtPosition(force * direction, hit.point);
		
		// Place the particle system for spawing out of place where we hit the surface!
		// And spawn a couple of particles
		if (hitParticles) {
			hitParticles.transform.position = hit.point;
			hitParticles.transform.rotation = Quaternion.FromToRotation(Vector3.up, hit.normal);
			hitParticles.Emit();
		}

		// Send a damage message to the hit object			
		hit.collider.SendMessageUpwards("ApplyDamage", damage, SendMessageOptions.DontRequireReceiver);
	}
	
	bulletsLeft--;

	// Register that we shot this frame,
	// so that the LateUpdate function enabled the muzzleflash renderer for one frame
	m_LastFrameShot = Time.frameCount;
	enabled = true;
	
	// Reload gun in reload Time		
	if (bulletsLeft == 0)
		Reload();			
}

function Reload () {

	// Wait for reload time first - then add more bullets!
	yield WaitForSeconds(reloadTime);

	// We have a clip left reload
	if (clips > 0) {
		clips--;
		bulletsLeft = bulletsPerClip;
	}
}

function GetBulletsLeft () {
	return bulletsLeft;
}

this is what I’d do:

var range = 100.0; 
var fireRate = 0.05; 
var force = 10.0; 
var damage = 5.0; 
var bulletsPerClip = 40; 
var clips = 20; 
var reloadTime = 0.5; 
var inaccuracy = 0.0; 
private var hitParticles : ParticleEmitter; 
var muzzleFlash : Renderer; 

private var bulletsLeft : int = 0; 
private var nextFireTime = 0.0; 
private var m_LastFrameShot = -1; 

function Start () { 
   hitParticles = GetComponentInChildren(ParticleEmitter); 
    
   // We don't want to emit particles all the time, only when we hit something. 
   if (hitParticles) 
      hitParticles.emit = false; 
   bulletsLeft = bulletsPerClip; 
} 

function LateUpdate() { 
   if (muzzleFlash) { 
      // We shot this frame, enable the muzzle flash 
      if (m_LastFrameShot == Time.frameCount) { 
         muzzleFlash.transform.localRotation = Quaternion.AngleAxis(Random.value * 360, Vector3.forward); 
         muzzleFlash.enabled = true; 

         if (audio) { 
            if (!audio.isPlaying) 
               audio.Play(); 
            audio.loop = true; 
         } 
      } else { 
      // We didn't, disable the muzzle flash 
         muzzleFlash.enabled = false; 
         enabled = false; 
          
         // Play sound 
         if (audio) 
         { 
            audio.loop = false; 
         } 
      } 
   } 
} 

function Fire () { 
   if (bulletsLeft == 0) 
      return; 
    
   // If there is more than one bullet between the last and this frame 
   // Reset the nextFireTime 
   if (Time.time - fireRate > nextFireTime) 
      nextFireTime = Time.time - Time.deltaTime; 
    
   // Keep firing until we used up the fire time 
   while( nextFireTime < Time.time  bulletsLeft != 0) { 
      FireOneShot(); 
      nextFireTime += fireRate; 
   } 
} 

function FireOneShot () { 
   var direction = Quaternion.Lerp (transform.TransformDirection(Vector3.forward), Random.rotation, inaccuracy); 
   var hit : RaycastHit; 
    
   // Did we hit anything? 
   if (Physics.Raycast (transform.position, direction, hit, range)) { 
      // Apply a force to the rigidbody we hit 
      if (hit.rigidbody) 
         hit.rigidbody.AddForceAtPosition(force * direction, hit.point); 
       
      // Place the particle system for spawing out of place where we hit the surface! 
      // And spawn a couple of particles 
      if (hitParticles) { 
         hitParticles.transform.position = hit.point; 
         hitParticles.transform.rotation = Quaternion.FromToRotation(Vector3.up, hit.normal); 
         hitParticles.Emit(); 
      } 

      // Send a damage message to the hit object          
      hit.collider.SendMessageUpwards("ApplyDamage", damage, SendMessageOptions.DontRequireReceiver); 
   } 
    
   bulletsLeft--; 

   // Register that we shot this frame, 
   // so that the LateUpdate function enabled the muzzleflash renderer for one frame 
   m_LastFrameShot = Time.frameCount; 
   enabled = true; 
    
   // Reload gun in reload Time       
   if (bulletsLeft == 0) 
      Reload();          
} 

function Reload () { 

   // Wait for reload time first - then add more bullets! 
   yield WaitForSeconds(reloadTime); 

   // We have a clip left reload 
   if (clips > 0) { 
      clips--; 
      bulletsLeft = bulletsPerClip; 
   } 
} 

function GetBulletsLeft () { 
   return bulletsLeft; 
}

inaccuracy is how random the direction is; 1 means it will shoot in any random way, 0 means straight, 0.25 would mean a max of a 45° random rotation from where you’re aiming, etc. I didn’t check exactly how your code works, but I think that should do it.

Operator ‘*’ cannot be used with a left hand side of type ‘float’ and a right hand side of type ‘UnityEngine.Quaternion’.

No appropriate version of ‘UnityEngine.Physics.Raycast’ for the argument list ‘(UnityEngine.Vector3, UnityEngine.Quaternion, UnityEngine.RaycastHit, float)’ was found.

The best overload for the method ‘UnityEngine.Quaternion.Lerp(UnityEngine.Quaternion, UnityEngine.Quaternion, float)’ is not compatible with the argument list ‘(UnityEngine.Vector3, UnityEngine.Quaternion, float)’.

Got these errors

Oh, sorry, I didn’t read through the code to see what direction was; I forgot it was a vector and not a rotation :?

this should work for the direction

var direction = Vector3.Slerp (transform.TransformDirection(Vector3.forward), Random.onUnitSphere, inaccuracy);