A respawn script for enemies.

Hey guys,
I’ve run into somewhat of a wall one might call it.
I have a simple respawn script for my enemies in my level (currently a very very simple one, for testing purposes).

I have all enemies in a list.

The script works by the killed enemy sending it’s id and also it’s respawn time to two separate lists.

The respawn script then checks the id against the list with enemies and when the corresponding respawn time reaches zero, the exact same monster which was killed is respawned.

It’s working great, but I just recently found out that if an enemy with a shorter respawn time than what’s left on the previously killed enemies respawn time the list goes out of range.

Could someone take a look at the code and see if you can find out what I’m missing.

(MonsterMaster, handles spawning initially and then respawning monsters defined in the inspector)

The code:

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

[System.Serializable]
public class MonsterMaster : MonoBehaviour {
	
	public EnemyClass[] enemies;
	public List<float> respawnTime;
	public List<int> enemyIDs;
	
	void Start () {
		respawnTime = new List<float>();
		enemyIDs = new List<int>();
		
		for(int x = 0; x < enemies.Length; x++){
			if(enemies[x].isSpawned == false){
				GameObject enemy;
				enemy = Instantiate(enemies[x].enemyPrefab, enemies[x].spawnPoint, Quaternion.identity) as GameObject;
				enemies[x].isSpawned = true;
				Enemy enemyScript;
				enemyScript = enemy.GetComponent<Enemy>();
				enemyScript.enemyId = enemies[x].id;
				enemyScript.health = enemies[x].health;
				enemyScript.enemyName = enemies[x].name;
				enemyScript.enemyGuild = enemies[x].guild;
				enemyScript.level = enemies[x].level;
				enemyScript.exp = enemies[x].experience;
				enemyScript.moveSpeed = enemies[x].moveSpeed;
				enemyScript.maxMoveDistance = enemies[x].maxMoveDistance;
				enemyScript.respawnTime = enemies[x].respawnTime;
				enemyScript.loot = enemies[x].loot;
			}
		}
	}
	
	void Update () {
		for(int x = 0; x < respawnTime.Count; x++){
			respawnTime[x] -= Time.deltaTime;
			for(int idCnt = 0; idCnt < enemyIDs.Count; idCnt++){
				for(int cnt = 0; cnt < enemies.Length; cnt++){
/*error here*/			if(enemyIDs.Count != 0 && enemies[cnt].id == enemyIDs[idCnt] && enemies[cnt].isSpawned == false && respawnTime[x] <= 0){
						GameObject enemy;
						enemy = Instantiate(enemies[cnt].enemyPrefab, enemies[cnt].spawnPoint, Quaternion.identity) as GameObject;
						enemies[cnt].isSpawned = true;
						Enemy enemyScript;
						enemyScript = enemy.GetComponent<Enemy>();
						enemyScript.enemyId = enemies[cnt].id;
						enemyScript.health = enemies[cnt].health;
						enemyScript.enemyName = enemies[cnt].name;
						enemyScript.enemyGuild = enemies[cnt].guild;
						enemyScript.level = enemies[cnt].level;
						enemyScript.exp = enemies[cnt].experience;
						enemyScript.moveSpeed = enemies[cnt].moveSpeed;
						enemyScript.maxMoveDistance = enemies[cnt].maxMoveDistance;
						enemyScript.respawnTime = enemies[cnt].respawnTime;
						enemyScript.loot = enemies[cnt].loot;
						enemyIDs.RemoveAt(idCnt);
						respawnTime.RemoveAt(x);
					}
				}
			}
		}
	}
}

The error:

ArgumentOutOfRangeException: Argument is out of range.
Parameter name: index
System.Collections.Generic.List`1[System.Single].get_Item (Int32 index) (at /Applications/buildAgent/work/84669f285f6a667f/mcs/class/corlib/System.Collections.Generic/List.cs:633)
MonsterMaster.Update () (at Assets/Scripts/Enemies/MonsterMaster.cs:42)

(mainly focusing on functionality at the moment)
The game in it’s current state:
https://dl.dropboxusercontent.com/u/163931410/Awesome/Awesome.html

Any tips for improvements are also highly appreciated!

Thanks for taking your time! :slight_smile:

I just sat down and rewrote the whole thing and somehow I got it working properly!

Thanks Benproductions for the reply, and thanks to anyone who was trying to help but didn’t get the time to reply!

Here’s the rewritten code:

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

[System.Serializable]
public class MonsterMaster : MonoBehaviour {
	
	public EnemyClass[] enemies;
	public List<float> respawnTime;
	public List<int> enemyIDs;
	
	void Start () {
		respawnTime = new List<float>();
		enemyIDs = new List<int>();
		
		for(int x = 0; x < enemies.Length; x++){
			if(enemies[x].isSpawned == false){
				GameObject enemy;
				enemy = Instantiate(enemies[x].enemyPrefab, enemies[x].spawnPoint, Quaternion.identity) as GameObject;
				enemies[x].isSpawned = true;
				Enemy enemyScript;
				enemyScript = enemy.GetComponent<Enemy>();
				enemyScript.enemyId = enemies[x].id;
				enemyScript.health = enemies[x].health;
				enemyScript.enemyName = enemies[x].name;
				enemyScript.enemyGuild = enemies[x].guild;
				enemyScript.level = enemies[x].level;
				enemyScript.exp = enemies[x].experience;
				enemyScript.moveSpeed = enemies[x].moveSpeed;
				enemyScript.maxMoveDistance = enemies[x].maxMoveDistance;
				enemyScript.respawnTime = enemies[x].respawnTime;
				enemyScript.loot = enemies[x].loot;
			}
		}
	}
	
	void Update () {
		for(int x = 0; x < respawnTime.Count; x++){
			respawnTime[x] -= Time.deltaTime;
			for(int respawnCnt = 0; respawnCnt < respawnTime.Count; respawnCnt++){
				if(respawnTime[respawnCnt] <= 0){
					for(int enemyCnt = 0; enemyCnt < enemies.Length; enemyCnt++){
						if(enemies[enemyCnt].isSpawned == false && enemyIDs[respawnCnt] == enemies[enemyCnt].id){
							Debug.Log (enemies[enemyCnt].id);
							GameObject enemy;
							enemy = Instantiate(enemies[enemyCnt].enemyPrefab, enemies[enemyCnt].spawnPoint, Quaternion.identity) as GameObject;
							enemies[x].isSpawned = true;
							Enemy enemyScript;
							enemyScript = enemy.GetComponent<Enemy>();
							enemyScript.enemyId = enemies[enemyCnt].id;
							enemyScript.health = enemies[enemyCnt].health;
							enemyScript.enemyName = enemies[enemyCnt].name;
							enemyScript.enemyGuild = enemies[enemyCnt].guild;
							enemyScript.level = enemies[enemyCnt].level;
							enemyScript.exp = enemies[enemyCnt].experience;
							enemyScript.moveSpeed = enemies[enemyCnt].moveSpeed;
							enemyScript.maxMoveDistance = enemies[enemyCnt].maxMoveDistance;
							enemyScript.respawnTime = enemies[enemyCnt].respawnTime;
							enemyScript.loot = enemies[enemyCnt].loot;
						}
					}
					respawnTime.RemoveAt(respawnCnt);
					enemyIDs.RemoveAt(respawnCnt);
				}
			}
		}
	}
}