RayCast Collision being weird

I am making a machine gun based on a RayCast script. When I hold down the mouse button it shoots correctly but when I shoot at air and then go back to a collider it doesn’t make the particles show up or shoot the enemies.

#pragma strict

var Effect : Transform;
var TheDammage = 100;
var shooting = false;
var random = .5;
var random2 = .5;

function Start ()
{
	random = .5;
	random2 = .5;
}

function Update () 
{	
	if (Input.GetMouseButtonDown(0))
	{
		shooting = true;
		Accuracy();
		Accuracy2();
		Shoot();
	}
	if (Input.GetMouseButtonUp(0))
	{
		shooting = false;
	}
}

function Accuracy ()
{
	if(shooting)
	{
		random = .51;
		yield WaitForSeconds(.09);
		random = .49;
		yield WaitForSeconds(.08);
		random = .53;
		yield WaitForSeconds(.09);
		random = .48;
		yield WaitForSeconds(.09);
		random = .52;
		yield WaitForSeconds(.07);
		random = .47;
		yield WaitForSeconds(.08);
		AccuracyRepeat();
	}
}

function Accuracy2 ()
{
	if(shooting)
	{
		random2 = .51;
		yield WaitForSeconds(.09);
		random2 = .47;
		yield WaitForSeconds(.1);
		random2 = .53;
		yield WaitForSeconds(.09);
		random2 = .48;
		yield WaitForSeconds(.09);
		random2 = .49;
		yield WaitForSeconds(.08);
		random2 = .52;
		yield WaitForSeconds(.07);
		Accuracy2Repeat();
	}
}

function AccuracyRepeat ()
{
	Accuracy();
}
function Accuracy2Repeat ()
{
	Accuracy2();
}


function Shoot () 
{
	if(shooting)
	{
		yield WaitForSeconds(.1);
		var hit : RaycastHit;
		var ray : Ray = Camera.main.ScreenPointToRay(Vector3(Screen.width*random, Screen.height*random2, 0));
		animation.Play("Recoil");
		if (Physics.Raycast (ray, hit, 100))
		{
		
			//Instanciate, spawn
			var particleClone = Instantiate(Effect, hit.point, Quaternion.LookRotation(hit.normal));
			Destroy(particleClone.gameObject, 2);
			hit.transform.SendMessage("ApplyDammage", TheDammage,SendMessageOptions.DontRequireReceiver);
			yield WaitForSeconds(0.1);
			ShootRepeat();
		}
	}
}
function ShootRepeat ()
{
	Shoot();
}

It’s because the Repeat() function is only called if you’re hitting something.

So it should become:

function Shoot ()
{
    if(shooting) 
    {
        var hit : RaycastHit;
        var ray : Ray = Camera.main.ScreenPointToRay(Vector3(Screen.width*0.5, Screen.height*0.5, 0));
        if (Physics.Raycast (ray, hit, 100))
        {
         
            //Instanciate, spawn
            var particleClone = Instantiate(Effect, hit.point, Quaternion.LookRotation(hit.normal));
            Destroy(particleClone.gameObject, 2);
            hit.transform.SendMessage("ApplyDammage", TheDammage,SendMessageOptions.DontRequireReceiver);
            yield WaitForSeconds(0.1);
            
        }
        Repeat();
    }
}

Instead of making a recursive function like this you could also do:

function Shoot ()
{
    while(shooting) 
    {
        var hit : RaycastHit;
        var ray : Ray = Camera.main.ScreenPointToRay(Vector3(Screen.width*0.5, Screen.height*0.5, 0));
        if (Physics.Raycast (ray, hit, 100))
        {
         
            //Instanciate, spawn
            var particleClone = Instantiate(Effect, hit.point, Quaternion.LookRotation(hit.normal));
            Destroy(particleClone.gameObject, 2);
            hit.transform.SendMessage("ApplyDammage", TheDammage,SendMessageOptions.DontRequireReceiver);
            
        }
        
        yield WaitForSeconds(0.1);
    }
}

This way you could remove the Repeat() coroutine function.

Note that I also moved the yield WaitForSeconds(0.1) outside of the if statement so that it will also wait that amount of time if we missed. Otherwise if you hold down the shooting button while missing and then move your mouse over an enemy the first moment is always a direct hit.