unity editor freezes on play, because of script

hey everyone,

I’m on Unity 5.5.2f1. i tried to make an enemy AI using navMeshAgent and a Finite State Machine. the script is below.

now when I added that script to my enemy and pressed play, the editor froze, and I can’t get out of unity unless I go to task manager and kill it.

i’m pretty certain it’s this script because when i remove it and add my other ai script, everything runs fine.
I’m fairly new to scripting in general, and even though i know i’m missing something in the script, i can’t find out what.

kind regards,

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

public class StateMachineAI : MonoBehaviour {

    public NavMeshAgent agent;

    public enum State
    {
        PATROL,
        CHASE,
        SHOOT,
        RUN
    }

    public State state;
    private bool alive;




    //vars for patrolling
    public GameObject[] waypoints;
    private int waypointIndex;
    public float patrolSpeed = .5f;

    //vars for chasing
    public float chaseSpeed = 1f;
    private float targetDistance;
    public GameObject target;

    //vars for seeing
    public float sightDist = 10f;
    public float heightMultiplier = 1.35f;
    public bool targetFound;


    //vars for running
    public float runSpeed = .7f;

    //vars for shooting
    public bool shooting;
    public Transform player;
    
    


	
	void Start () {

        agent = GetComponent<NavMeshAgent>();
        agent.updatePosition = true;
        agent.updateRotation = true;

        waypoints = GameObject.FindGameObjectsWithTag("waypoint");
        waypointIndex = Random.Range(0, waypoints.Length);

        alive = true;
        shooting = false;
        targetFound = false;

        state = StateMachineAI.State.PATROL;
	}
	
	
	void Update () {
        StartCoroutine("FSM");
        if (targetFound)
        {
            if (Vector3.Distance(target.transform.position, transform.position) >= GetComponentInChildren<RayGun>().weaponRange && GetComponent<enemyHealth>().curHealth > 20)
            {
                state = StateMachineAI.State.CHASE;
            }
            if (Vector3.Distance(target.transform.position, transform.position) <= GetComponentInChildren<RayGun>().weaponRange && GetComponent<enemyHealth>().curHealth > 20)
            {
                state = StateMachineAI.State.SHOOT;
            }
            if (GetComponent<enemyHealth>().curHealth <= 20)
            {
                state = StateMachineAI.State.RUN;
            }
            else
            {
                state = StateMachineAI.State.PATROL;
            }
        }
	}

    IEnumerator FSM()
    {
        while(alive)
            switch (state)
            {
                case State.PATROL:
                    Patrol();
                    break;

                case State.CHASE:
                    Chase();
                    break;

                case State.SHOOT:
                    Shoot();
                    break;

                case State.RUN:
                    Run();
                    break;
            }

        yield return null;
    }

    void Patrol()
    {
        agent.speed = patrolSpeed;
        if (Vector3.Distance(this.transform.position, waypoints[waypointIndex].transform.position) >= 2)
        {
            agent.SetDestination(waypoints[waypointIndex].transform.position);
        }
        else if (Vector3.Distance(this.transform.position, waypoints[waypointIndex].transform.position) <= 2)
        {
            waypointIndex = Random.Range(0, waypoints.Length);
        }
        //else
       // {
            //should be a still animation, dunno what to do with this
       // }
    }

    void Chase()
    {
        agent.speed = chaseSpeed;
        agent.SetDestination(target.transform.position);
    }

    void Shoot()
    {
        //something to initiate the raygun script when target is spotted
        shooting = true;
        
        
    }

    void Run()
    {
        agent.speed = runSpeed;
        agent.SetDestination(waypoints[waypointIndex].transform.position);
        shooting = false;
    }

    private void FixedUpdate() //sighting raycast function
    {
        RaycastHit hit;
        Debug.DrawRay(transform.position + Vector3.up * heightMultiplier, transform.forward * sightDist, Color.green);
        Debug.DrawRay(transform.position + Vector3.up * heightMultiplier, (transform.forward + transform.right).normalized * sightDist, Color.green);
        Debug.DrawRay(transform.position + Vector3.up * heightMultiplier, (transform.forward - transform.right).normalized * sightDist, Color.green);

        if (Physics.Raycast(transform.position + Vector3.up * heightMultiplier, transform.forward, out hit, sightDist))
        {
            if (hit.collider.gameObject.tag == "Player")
            {
                targetFound = true;
                //state = StateMachineAI.State.CHASE;
                target = hit.collider.gameObject;
            }
        }

        if (Physics.Raycast(transform.position + Vector3.up * heightMultiplier, (transform.forward + transform.right).normalized, out hit, sightDist))
        {
            if (hit.collider.gameObject.tag == "Player")
            {
                targetFound = true;
                //state = StateMachineAI.State.CHASE;
                target = hit.collider.gameObject;
            }
        }

        if (Physics.Raycast(transform.position + Vector3.up * heightMultiplier, (transform.forward - transform.right).normalized, out hit, sightDist))
        {
            if (hit.collider.gameObject.tag == "Player")
            {
                targetFound = true;
                //state = StateMachineAI.State.CHASE;
                target = hit.collider.gameObject;
            }
        }
    }
}

Looking through your code, this sticks out:

IEnumerator FSM()
     {
         while(alive)
             switch (state)
             {
                 case State.PATROL:
                     Patrol();
                     break;
 
                 case State.CHASE:
                     Chase();
                     break;
 
                 case State.SHOOT:
                     Shoot();
                     break;
 
                 case State.RUN:
                     Run();
                     break;
             }
 
         yield return null;
     }

Your yield statement is not contained in the while loop.

fix it like this:

IEnumerator FSM()
{
    while (alive)
    {
        switch (state)
        {
            case State.PATROL:
                Patrol();
                break;

            case State.CHASE:
                Chase();
                break;

            case State.SHOOT:
                Shoot();
                break;

            case State.RUN:
                Run();
                break;
        }

        yield return null;
    }
}