When shooter script is attached and I hit play, Unity crashes?

Whenever my ‘LaserShooter’ script is attached and I press play to test, I get the spinning wheel (on my mac). I have to force quit Unity and restart. Here is the script that causes the crash/lag:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class LaserShooter : MonoBehaviour {

public GameObject projectile;
private int modChoose;
private float speed = 50;
private bool access;
Vector3 rayOrigin = new Vector3();
Vector3 direction = new Vector3 (0, 0, -1);
Vector3 pos1 = new Vector3 (-7, 2, 12);
Vector3 pos2 = new Vector3 (1, 2, 12);
Vector3 pos3 = new Vector3 (7, 2, 12);
Quaternion spawnRotation = Quaternion.Euler(90,0,0);

void Start () {
	modChoose = Random.Range (1,4);
	access = true;
	spawn ();
	//modChoose is picking which module to shoot from.
}

void spawn () {
	if (access == true) {
		if (modChoose == 1) {
			GameObject bullet = Instantiate (projectile, pos1, spawnRotation) as GameObject;
			bullet.GetComponent<Rigidbody> ().AddForce (-transform.forward * speed);
			rayOrigin = pos1;
			checkAccess ();
			//If the first module is picked, fire a bullet from a specific pos.
		}

		if (modChoose == 2) {
			GameObject bullet = Instantiate (projectile, pos2, spawnRotation) as GameObject;
			bullet.GetComponent<Rigidbody> ().AddForce (-transform.forward * speed);
			modChoose = Random.Range (1, 4);
			rayOrigin = pos2;
			checkAccess ();
		}

		if (modChoose == 3) {
			GameObject bullet = Instantiate (projectile, pos3, spawnRotation) as GameObject;
			bullet.GetComponent<Rigidbody> ().AddForce (-transform.forward * speed);
			modChoose = Random.Range (1, 4);
			rayOrigin = pos3;
			checkAccess ();
		}
	}
}

void checkAccess() {
	while (Physics.Raycast (rayOrigin, direction, 30)) {
		access = false;
	}
	access = true;
	selectRandom ();

}

void selectRandom() {
	spawn ();
}
}

while (Physics.Raycast (rayOrigin, direction, 30)) {
access = false;
}

If this Raycast doesn’t hit anything it will be looping infinitely and doesn’t allow your code to continue. If you need it to keep raycasting on every update then you should do it with coroutine.

IEnumerator checkAccess() {
     while (Physics.Raycast (rayOrigin, direction, 30)) {
         access = false;
         yield return new WaitForEndOfFrame();
     }
     access = true;
     selectRandom ();
 }

And then you need to use StartCoroutine(checkAccess()); when calling it.

No point on using a Coroutine in this ocassion as MonoBehaviour provides a perfect way to loop with the Update().
try this:

public class LaserShooter : MonoBehaviour
{
    public GameObject projectile;

    private GameObject bullet;
    private int modChoose;
    private float speed = 50;
    Vector3 rayOrigin = new Vector3();
    Vector3 direction = new Vector3(0, 0, -1);
    Vector3[] pos = new Vector3[] {
        new Vector3(-7, 2, 12),
        new Vector3(1, 2, 12),
        new Vector3(7, 2, 12),};
    
    Quaternion spawnRotation = Quaternion.Euler(90, 0, 0);

    void Start()
    {
        modChoose = Random.Range(1, 4);
        spawn();
    }

    void Update()
    {
        if (!Physics.Raycast(rayOrigin, direction, 30))
        {
            spawn();
        }
    }

    void spawn()
    {
            switch (modChoose)
            {
                case 1:
                    bullet = Instantiate(projectile, pos[modChoose-1], spawnRotation) as GameObject;
                    bullet.GetComponent<Rigidbody>().AddForce(-transform.forward * speed);
                    break;
                //If the first module is picked, fire a bullet from a specific pos.

                case 2:
                    bullet = Instantiate(projectile, pos[modChoose-1], spawnRotation) as GameObject;
                    bullet.GetComponent<Rigidbody>().AddForce(-transform.forward * speed);
                    break;

                case 3:
                    bullet = Instantiate(projectile, pos[modChoose-1], spawnRotation) as GameObject;
                    bullet.GetComponent<Rigidbody>().AddForce(-transform.forward * speed);
                    break;
            }
        modChoose = Random.Range(1, 4);
        rayOrigin = pos[modChoose-1];
            
    }
}

Keep in mind that the simplest way to achive something is always the best.
Note: the physics.Raycast check you run is kinda vague you should define what is it you expect it to hit. I ll assume you use it to check if a projectile is already been fired from that position so the projectiles don’t override each other, if that s the case then either add a tag on the projectile and check against it or add a layer mask on them and check that. Cheers.