Script makes Uniy Freeze
Basically i have AI movement around destination points ( cubes ). When there is only 1 Patrolling AI.. everything works excellent but when i add the second AI it works for aprox. 10 secs and freezes my unity.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
public class SpiderScript : MonoBehaviour {
public Transform player;
public List<GameObject> DestinationPoints;
private Animator anim;
public float speed;
public float alertDistance;
public float walkingDistance;
public float attackingDistance;
public int mintime;
public int maxtime;
public float remainingDistance;
private Vector3 Direction;
private NavMeshAgent agent;
private int selectedDestination;
// Use this for initialization
void Start()
{
anim = GetComponent<Animator>();
agent = GetComponent<NavMeshAgent>();
agent.enabled = false;
}
// Update is called once per frame
void Update()
{
if(agent.enabled == true && agent.remainingDistance < remainingDistance)
{
agent.enabled = false;
anim.SetBool("isWalking", false);
anim.SetBool("isIdle", true);
StartCoroutine(RandomMovement());
}
//idle
//walk
//run
//attack
if (Vector3.Distance(player.position, transform.position) < alertDistance &&
Vector3.Distance(player.position, transform.position) > walkingDistance)
{
agent.enabled = false;
anim.SetBool("isAlert", true);
anim.SetBool("isWalking", false);
anim.SetBool("isAttacking", false);
anim.SetBool("isIdle", false);
}
else if (Vector3.Distance(player.position, transform.position) <= walkingDistance)
{
agent.enabled = true;
/* Direction = player.position - transform.position;
Direction.y = 0;
transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(Direction), 0.9f * Time.deltaTime);
transform.Translate(0, 0, speed); */
agent.SetDestination(player.transform.position);
anim.SetBool("isWalking", true);
anim.SetBool("isAttacking", false);
anim.SetBool("isAlert", false);
anim.SetBool("isIdle", false);
if (Direction.magnitude <= attackingDistance)
{
anim.SetBool("isAttacking", true);
anim.SetBool("isWalking", false);
}
}
else if (anim.GetBool("isIdle") == false && agent.enabled == false)
{
anim.SetBool("isWalking", false);
anim.SetBool("isAttacking", false);
anim.SetBool("isAlert", false);
anim.SetBool("isIdle", true);
StartCoroutine(RandomMovement());
}
}
public IEnumerator RandomMovement()
{
int index = Random.Range(mintime, maxtime);
Debug.Log("randomtime" + index);
yield return new WaitForSeconds(index);
int index2 = Random.Range(1, 3);
switch (index2)
{
case 1:
Debug.Log("Keep idle");
StartCoroutine(RandomMovement());
break;
case 2:
Debug.Log("Move");
agent.enabled = true;
int lastDestination = selectedDestination;
selectedDestination = Random.Range(0, DestinationPoints.Count);
while (selectedDestination == lastDestination || DestinationPoints[selectedDestination].GetComponent<Destination>().isUsed == true)
{
selectedDestination = Random.Range(0, DestinationPoints.Count);
}
DestinationPoints[selectedDestination].GetComponent<Destination> ().isUsed = false;
agent.SetDestination(DestinationPoints [selectedDestination].transform.position);
DestinationPoints[selectedDestination].GetComponent<Destination> ().isUsed = true;
anim.SetBool("isWalking", true);
anim.SetBool("isAttacking", false);
anim.SetBool("isAlert", false);
anim.SetBool("isIdle", false);
break;
}
}
}
Destination script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Destination : MonoBehaviour {
public bool isUsed = false;
}
Your coroutine invokes itself and contains a while loop.
@meat5000 Hey, thanks for the replay. What would be the correct way to invoke coroutine in this example?
It is possible to run multiple coroutines. Invoking one will not replace one thats running...they will stack up. Coroutines halt the main thread whilst they are running and so having a while loop is a dangerous thing if it is questionable whether the break-out conditions will be met.
It seems to me that this Random$$anonymous$$ovement just needs to be a normal Function which you call to present a new random value. I'm not sure there's any advantage to running this as a coroutine.