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;
}
}
}
}
Answer by PaulFarver · Oct 20, 2017 at 02:55 PM
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;
}
}
Your answer
Follow this Question
Related Questions
Question about NavMesh and Rigidbody 0 Answers
Question About NavMesh Agent and rotation 1 Answer
How to get the closest object in the navMesh and making the agent move towards it 1 Answer
Enemy AI for Multiplayer (using NavMeshAgent) unity 5.6.5f1 0 Answers
How Can I make a prefab using navmesh alternate destination targets? 0 Answers