Game freezes up for a second after executing code, how do I fix this?

Hello, I created a script to have a boss character fire a laser using the line renderer, it works well enough for my purposes but to get the effect my code is kind of sloppy and during part of the code execution towards the end the game will freeze for a split second before resuming. How can I fix or trim down my code to prevent this?

public class anemoneLaser : MonoBehaviour {

    public BossBehavior bossBehavior;

    public float laserWidth;
    public float laserTimer;
    public float startTimer;
    private float nextShot;
    private float nextStartUp;
    public bool laserStarting;
    public bool laserReady;
    public bool laserOff;
    public float minWidth = 0;
    public float maxWidth = 2.3f;
    LineRenderer redLaser;
    ParticleSystem laserSparks;

    private AudioSource laserCharge;
    private AudioSource laserShot;

    // Use this for initialization
	void Start ()
    {
        GameObject bossBehaviorObject = GameObject.FindWithTag("Boss");
        if (bossBehaviorObject != null)
        {
            bossBehavior = bossBehaviorObject.GetComponent<BossBehavior>();
        }
        if (bossBehavior == null)
        {
            Debug.Log("Cannot find 'BossBehavior' script");
        }

        AudioSource[] laserSounds = GetComponents<AudioSource>();
        laserCharge = laserSounds[0];
        laserShot = laserSounds[1];

        laserTimer = nextShot;
        startTimer = nextStartUp;

        laserWidth = 0;

        redLaser = GetComponent<LineRenderer>();
        SpriteRenderer spriteRenderer = GetComponent<SpriteRenderer>();
        redLaser.sortingLayerID = spriteRenderer.sortingLayerID;
        redLaser.sortingOrder = spriteRenderer.sortingOrder;
        redLaser.widthMultiplier = laserWidth;

        laserSparks = GetComponentInChildren<ParticleSystem>();
        laserSparks.Pause();
	}
	
	// Update is called once per frame
	void Update ()
    {
        redLaser = GetComponent<LineRenderer>();
        redLaser.widthMultiplier = laserWidth;

        if (laserWidth < 0)
        {
            laserWidth = 0;
        }
        // Starting countdown for laser
        if (laserStarting)
        {
            laserOff = false;
            startTimer -= Time.deltaTime;
        }

        if (bossBehavior.bossActive && laserStarting && startTimer < 0 && !laserOff)
        {
            laserWidth = 0.1f; //sets laser to a minimum width so player knows its about to go off
            laserStarting = false;
            laserCharge.Play();
            laserSparks.Play();
            StartCoroutine(PrepareToFire());   
        }
        //Laser ready to fire
        if (laserReady)
        {
            laserTimer -= Time.deltaTime;
        }

        if (bossBehavior.bossActive && laserReady && laserTimer < 0 && !laserOff)
        {
            
            StartCoroutine(FirinMahLaser());
        }

	}
    IEnumerator PrepareToFire()
    {
        yield return new WaitForSeconds(0.8f);
        Debug.Log("PrepareToFire()");
        startTimer = nextStartUp;
        laserReady = true;
        
    }
    // Increases width of laser to maxWidth value before finishing and going into Cool Down
    IEnumerator FirinMahLaser()
    {
        //laserShot.Play(); //Not sure where to place this yet so it doesn't play more then once
        yield return new WaitForSeconds(3.5f);
        laserTimer = nextShot;
        
        if (laserWidth < maxWidth && !laserOff)
        {
            Debug.Log("Adding Width");
            laserWidth += 0.1f;
        }
        else if (laserWidth >= maxWidth && !laserOff)
        {
            yield return new WaitForSeconds(2.0f);
            Debug.Log("Laser Width at Max");
            StartCoroutine(CoolingOff());
        }

    }
    //Called to reduce width and turn off laser then move on to prepare for the next firing
    IEnumerator CoolingOff()
    {
        while (laserWidth > minWidth && !laserOff)
        {
            Debug.Log("Cooling off WHILE loop");
            laserWidth -= 0.01f;
        }
        if(laserWidth <= minWidth && !laserOff)
        {
            
            Debug.Log("WHILE loop broken");
            laserSparks.Stop();
            laserOff = true;
            laserStarting = false;
            laserReady = false;
            yield return new WaitForSeconds(10.0f);
            StartCoroutine(PrepNext());
        }
    }
    //Prepare for next laser
    IEnumerator PrepNext()
    {
        Debug.Log("PrepNext()");
        
        laserWidth = 0;
        laserTimer = nextShot;
        startTimer = nextStartUp;
        yield return new WaitForSeconds(2.0f);
        laserStarting = true;
    }
   //TODO Add collision to laser
}

The freeze up happens after the while loop is broken, maybe that’s what is creating the lag? Any help would be appreciated. Thanks.

Hey, so i had a look at your code and its likely that the while loop in your CoolingOff co-routine is whats causing the problem.

I assume you dont want your CoolOff to complete in a single frame which is whats its currently doing. If you add the line. yield return null; below the laserWidth -= 0.01f this will make your co-routine yield for a frame and it will check the while loop again in the next frame and they - the 0.01 and so on until (laserWidth < minWidth && !laserOff).

Also i noticed that your cooldown(and other variables) is fps depended, this means that laserWidth -= 0.01f; will be called each frame and therefor doesnt take into account actual time.

So for example if you have 60fps your laserWidth will be -0.6 in 1 second. but for whatever reason if your fps is 30 it will take 2 seconds to get to -0.6.
you should look into Time.deltatime to fix this problem.

Hope this helps ~Scott