A better script for a machine gun?

I’m trying to modify the Angry Bots autofire script.

So, you want to be able to either:

a.) Tap the fire button and shoot only one shot

b.) Hold down the fire button and shoot repeatedly at a fixed rate

The original script just played and stopped the audioclip “onStartFire” and OnStopFire" signals. As it stands now, it fires one shot cleanly using the “PlayClipAtPoint” command but doesn’t rapidfire. I’m sure it’s because I don’t understand the Vector3 command.

@script RequireComponent (PerFrameRaycast)

var bulletPrefab : GameObject;
var spawnPoint : Transform;
var frequency : float = 10;
var coneAngle : float = 1.5;
var firing : boolean = false;
var damagePerSecond : float = 20.0;
var forcePerSecond : float = 20.0;
var hitSoundVolume : float = 0.5;
var gunPlay : AudioClip;
var gunStop : AudioSource;

var muzzleFlashFront : GameObject;

private var lastFireTime : float = -1;
private var raycast : PerFrameRaycast;

function Awake () {
	muzzleFlashFront.SetActive (false);

	raycast = GetComponent.<PerFrameRaycast> ();
	if (spawnPoint == null)
		spawnPoint = transform;
}

function Update () {
	if (firing) {

		if (Time.time > lastFireTime + 1 / frequency) {
			// Spawn visual bullet
			var coneRandomRotation = Quaternion.Euler (Random.Range (-coneAngle, coneAngle), Random.Range (-coneAngle, coneAngle), 0);
			var go : GameObject = Spawner.Spawn (bulletPrefab, spawnPoint.position, spawnPoint.rotation * coneRandomRotation) as GameObject;
			var bullet : SimpleBullet = go.GetComponent.<SimpleBullet> ();

			lastFireTime = Time.time;

			// Find the object hit by the raycast
			var hitInfo : RaycastHit = raycast.GetHitInfo ();
			if (hitInfo.transform) {
				// Get the health component of the target if any
				var targetHealth : Health = hitInfo.transform.GetComponent.<Health> ();
				if (targetHealth) {
					// Apply damage
					targetHealth.OnDamage (damagePerSecond / frequency, -spawnPoint.forward);
				}

				// Get the rigidbody if any
				if (hitInfo.rigidbody) {
					// Apply force to the target object at the position of the hit point
					var force : Vector3 = transform.forward * (forcePerSecond / frequency);
					hitInfo.rigidbody.AddForceAtPosition (force, hitInfo.point, ForceMode.Impulse);
				}

				// Ricochet sound
				var sound : AudioClip = MaterialImpactManager.GetBulletHitSound (hitInfo.collider.sharedMaterial);
				AudioSource.PlayClipAtPoint (sound, hitInfo.point, hitSoundVolume);

				bullet.dist = hitInfo.distance;
			}
			else {
				bullet.dist = 1000;
			}
		}
	}
}

function OnStartFire () {
	if (Time.timeScale == 0)
		return;

	firing = true;

	muzzleFlashFront.SetActive (true);

	//if (audio && gunPlay.isPlaying){
	//	yield WaitForSeconds (gunPlay.clip.length);
	//	gunPlay.Play ();
	//}
	//else {
		audio.PlayClipAtPoint (gunPlay,Vector3 (5, 1, 2));
	//}
}

function OnStopFire () {
	firing = false;

	muzzleFlashFront.SetActive (false);
	
	if (audio){
		
		gunStop.Play ();
	}
	//else {
	//	gunStop.Play ();
	//}
}

This worked for me very well. One caveat is that I had to pitch the single shot audioclip down an octave in order to import it into Unity. Then I pitched it back up via the audiosource. In addition, I added a tracer sound to the bullet prefab to get bullet action subtly across the screen. Very nice indeed! I found just using a single audioclip work well enough in tandem with random pitching. Adding more clips on the firing sound didn’t yield better results IMO. However, the recoil/reverb action on “mouse up” is nice with some variance. Hope this helps someone.

#pragma strict
@script RequireComponent(AudioSource)

var gunLoop : AudioSource;
var gunLoopSounds: AudioClip[]; // set the array size and fill the elements with the sounds
var gunStop : AudioSource;
var gunStopSounds: AudioClip[]; // set the array size and fill the elements with the sounds
var distortion: AudioDistortionFilter;




function Update () {

	if(Input.GetMouseButtonDown(0)) {
 		gunLoop.loop = true; // turn looping on
 		//gunLoop.pitch = Random.Range(2.30,2.35);
 		PlayRandomGunLoop(); // and start sound
 		//gunLoop.loop = false; // turn looping off to stop sound;
 	
 	}
 	
 	if(Input.GetMouseButton(0)) {
 		
 		gunLoop.pitch = Random.Range(2.18,2.28); //2.28, 2.31 old values
 		//gunLoop.volume = Random.Range(0.98,1);
 		//distortion.distortionLevel = Random.Range (0.1,0.13);
 	
 	}
 	
	
	if(Input.GetMouseButtonUp(0)) {
 		gunLoop.loop = false; // turn looping off to stop sound;
 		PlayRandomGunStop();	// and start sound	
	
	}
	
}
 
function PlayRandomGunLoop(){ // call this function to play a random sound

    //if (gunLoop.isPlaying) return; // don't play a new sound while the last hasn't finished
       	gunLoop.clip = gunLoopSounds[Random.Range(0,gunLoopSounds.length)];
       	gunLoop.Play();
	}
	
function PlayRandomGunStop(){ // call this function to play a random sound
    //if (gunStop.isPlaying) return; // don't play a new sound while the last hasn't finished
    	gunStop.clip = gunStopSounds[Random.Range(0,gunStopSounds.length)];
    	gunStop.pitch = Random.Range(1.32,1.42);
    	gunStop.Play();
}