Unity crashing... For some reason

I do know a few details about it. I am trying to instantiate a prefab which creates an overlap sphere and when the overlapsphere hits a player, that’s when everything crashes.

So the problem is, how do I debug this? My code always looks perfectly fine to me but I know it isn’t lol. I might not be the best coder but with a few hours I can usually debug my problems. Also, can this damage my project in any way? Should I create a backup?

Here’s the code if anyone’s interested:

using UnityEngine;
using System.Collections;

public class Turret : MonoBehaviour {

	private int expireTime = 10;
	private int projectileDamage = 20;
	private float cooldown = 2;
	private float cooldownBetweenProjectiles = 0.1f;
	public GameObject explosion;
	public string creator;
	private PlayerStats statsScript;
	
	public int health = 50;
	private int radius = 100;
	private Collider [] hitObjects;
	private bool aquireTarget = true;
	private bool fire = true;
	private float fireUntil = 0;
	private float fireDuration = 1;
	private bool fireNextProjectile = true;
	
	public GameObject projectile;
	private float randomRotationX = 25;
	private float randomRotationY = 25;
	private Transform target;
	private Vector3 firePosition;
	private Quaternion fireRotation;
	
	// Use this for initialization
	void Start ()
	{
		//Destroy the object after a while
		StartCoroutine(expire());
		target = null;
	}
	
	// Update is called once per frame
	void Update ()
	{
		if(health <= 0)
		{
			//Destroy the object if it loses all it's HP
			destroy();
		}
		
		if(aquireTarget == true)
		{
			//If a target needs to be aquired, create an overlap sphere and call the chooseTarget function
			hitObjects = Physics.OverlapSphere(transform.position, radius);
			chooseTarget();
			aquireTarget = false;
		}

		if(target != null)
		{
			//If there is a target, rotate towards it
			transform.LookAt(target.position);
			
			if(fire == true)
			{
				//If the turret is allowed to fire, do so
				fireProjectiles();
				fire = false;
			}
		}
	}
	
	void chooseTarget()
	{
		//Reset the target first
		target = null;
		
		for(int i = 0; i < hitObjects.Length; i++)
		{
			//If the target is a player, the function is finished.
			if((hitObjects*.transform.tag == "Player1" && creator == "Player2") ||*

_ (hitObjects*.transform.tag == “Player2” && creator == “Player1”))_
_
{_
_ target = hitObjects.transform;
break;
}*_

* //If there’s no player in range pick the closest enemy turret.*
_ else if(hitObjects*.transform.tag == “Turret” &&
((hitObjects.GetComponent().creator == “Player1” && creator == “Player2”) ||
(hitObjects.GetComponent().creator == “Player2” && creator == “Player1”)))
{
target = hitObjects.transform;
//Going to put distance code and sorting here later on…
}
}
}*_

* IEnumerator CD()*
* {*
* //Cooldown until next burst of projecetiles*
* yield return new WaitForSeconds(cooldown);*
* fire = true;*
* }*

* IEnumerator smallCD()*
* {*
* //Cooldown between every projectile fired*
* yield return new WaitForSeconds(cooldownBetweenProjectiles);*
* fireNextProjectile = true;*
* }*

* void fireProjectiles()*
* {*
* //Start cooldown until next burst*
* StartCoroutine(CD());*
* //Set an amount of time for which the turret is allowed to fire*
* fireUntil = Time.time + fireDuration;*

* //Fire for the duration of time*
* while(Time.time < fireUntil)*
* {*
* //This is set to true after a small amount of time*
* if(fireNextProjectile == true)*
* {*
* //Start projectile cooldown*
* StartCoroutine(smallCD ());*
* fireNextProjectile = false;*

* //Fire position in front of the turret and a slightly randomized aim*
* firePosition = transform.TransformPoint(0, 0, 1);*
* fireRotation = randomize(Quaternion.Euler(new Vector3(transform.eulerAngles.x, transform.eulerAngles.y, 0)));*

* //Instantiate the projectile for all players*
* networkView.RPC(“fireProjectile”, RPCMode.All, firePosition, fireRotation, creator);*
* }*
* }*
* }*

* IEnumerator expire()*
* {*
* //Destroy the object after an amount of seconds*
* yield return new WaitForSeconds(expireTime);*
* destroy();*
* }*

* void destroy()*
* {*
* //Create an explosion and destroy the object*
* Instantiate(explosion, transform.position, transform.rotation);*
* Destroy(gameObject);*
* }*

* [RPC]*
* void fireProjectile(Vector3 position, Quaternion rotation, string createdBy)*
* {*
* //Instantiate projectile and set damage and creator in it’s script*
* GameObject p = Instantiate(projectile, position, rotation) as GameObject;*
* p.GetComponent().setDamage(projectileDamage);*
* p.GetComponent().setCreator(createdBy);*
* }*

* Quaternion randomize(Quaternion rot)*
* {*
* //Modify the rotation slightly*
* float randomX = Random.Range(-randomRotationX / 2, randomRotationX / 2);*
* float randomY = Random.Range(-randomRotationY / 2, randomRotationY / 2);*
* return Quaternion.Euler(new Vector3(rot.eulerAngles.x + randomX, rot.eulerAngles.y + randomY, rot.eulerAngles.z));*
* }*
}

So I’m not entirely sure what created the crash but I narrowed it down to the while-loop in the fireProjectiles() function. I removed the IENumerator and bool controlling the firerate and instead put a for loop in a IENumerator which then called the function to fire projectiles. A lot less messy and appearantly non-crashing.

Here’s the working code if anyone’s going to need this:

using UnityEngine;
using System.Collections;

public class Turret : MonoBehaviour {

	private int expireTime = 10;
	private int projectileDamage = 20;
	private int amountOfProjectiles = 10;
	private float cooldown = 2;
	private float cooldownBetweenfiring = 0.1f;
	public GameObject explosion;
	public string creator;
	private PlayerStats statsScript;
	
	public int health = 50;
	private int radius = 100;
	private Collider [] hitObjects;
	private bool aquireTarget = true;
	private bool fireNow = true;
	
	public GameObject projectile;
	private float randomRotationX = 7.5f;
	private float randomRotationY = 7.5f;
	private Transform target;
	private Vector3 firePosition;
	private Quaternion fireRotation;
	
	// Use this for initialization
	void Start ()
	{
		//Destroy the object after a while
		StartCoroutine(expire());
		target = null;
		transform.parent = GameObject.Find("Creatures").transform;
	}
	
	// Update is called once per frame
	void Update ()
	{
		if(health <= 0)
		{
			//Destroy the object if it loses all it's HP
			destroy();
		}
		
		if(aquireTarget == true)
		{
			//If a target needs to be aquired, create an overlap sphere and call the chooseTarget function
			hitObjects = Physics.OverlapSphere(transform.position, radius);
			chooseTarget();
			aquireTarget = false;
		}

		if(target != null)
		{
			//If there is a target, rotate towards it
			transform.LookAt(target.position);
			
			if(fireNow == true)
			{
				//If the turret is allowed to fire, do so
				StartCoroutine(fire ());
				fireNow = false;
			}
		}
		else if(target == null && fireNow == true)
		{
			aquireTarget = true;
		}
	}
	
	void chooseTarget()
	{
		//Reset the target first
		target = null;
		
		for(int i = 0; i < hitObjects.Length; i++)
		{
			//If the target is a player, the function is finished.
			if((hitObjects*.transform.tag == "Player1" && creator == "Player2") ||*

_ (hitObjects*.transform.tag == “Player2” && creator == “Player1”))_
_
{_
_ target = hitObjects.transform;
break;
}*_

* //If there’s no player in range pick the closest enemy turret.*
_ else if(hitObjects*.transform.tag == “Turret” &&
((hitObjects.GetComponent().creator == “Player1” && creator == “Player2”) ||
(hitObjects.GetComponent().creator == “Player2” && creator == “Player1”)))
{
target = hitObjects.transform;
//Going to put distance code and sorting here later on…
}
}
}*_

* IEnumerator CD()*
* {*
* //Cooldown until next burst of projecetiles*
* yield return new WaitForSeconds(cooldown);*
* aquireTarget = true;*
* fireNow = true;*
* }*

* IEnumerator fire()*
* {*
* //Start cooldown*
* StartCoroutine(CD ());*

* //Loop for amount of projectiles to fire*
* for(int i = 0; i < amountOfProjectiles; i++)*
* {*
* //Cooldown between every projectile fired*
* yield return new WaitForSeconds(cooldownBetweenfiring);*
* fireProjectiles();*
* }*

* target = null;*
* }*

* void fireProjectiles()*
* {*
* //Fire position in front of the turret and a slightly randomized aim*
* firePosition = transform.TransformPoint(0, 0, 1);*
* fireRotation = randomize(Quaternion.Euler(new Vector3(transform.eulerAngles.x, transform.eulerAngles.y, 0)));*

* //Instantiate the projectile for all players*
* networkView.RPC(“fireProjectile”, RPCMode.All, firePosition, fireRotation, creator);*
* }*

* IEnumerator expire()*
* {*
* //Destroy the object after an amount of seconds*
* yield return new WaitForSeconds(expireTime);*
* destroy();*
* }*

* void destroy()*
* {*
* //Create an explosion and destroy the object*
* Instantiate(explosion, transform.position, transform.rotation);*
* Destroy(gameObject);*
* }*

* [RPC]*
* void fireProjectile(Vector3 position, Quaternion rotation, string createdBy)*
* {*
* //Instantiate projectile and set damage and creator in it’s script*
* GameObject p = Instantiate(projectile, position, rotation) as GameObject;*
* p.GetComponent().setDamage(projectileDamage);*
* p.GetComponent().setCreator(createdBy);*
* }*

* Quaternion randomize(Quaternion rot)*
* {*
* //Modify the rotation slightly*
* float randomX = Random.Range(-randomRotationX / 2, randomRotationX / 2);*
* float randomY = Random.Range(-randomRotationY / 2, randomRotationY / 2);*
* return Quaternion.Euler(new Vector3(rot.eulerAngles.x + randomX, rot.eulerAngles.y + randomY, rot.eulerAngles.z));*
* }*
}

In fireProjectiles(), you have this while loop:

while(Time.time < fireUntil)

From a (very) quick read, it looks to me like Time.time isn’t advancing during this loop, which could imply an infinite loop. Worth checking out?

If that is the problem, you could quickly fix the problem by making that function a coroutine which waits one frame before re-checking the loop condition, or otherwise refactoring so that you’re running those checks once per frame, instead of all at once.