I’m using some dictionaries to put monsters into my grid map. I’m trying to call a method that will choose a random key from the dictionary of monster types (AvailableMonsters) by converting my dictionary keys to a list (MonsterKeys) and choosing by random index. However, whenever I reference the list of keys in the method that places the objects, I get an index out of range error on the MonsterKeys list. I have tried hard-coding the value to 0 or 1 and still get the same error, or a NullReferenceException on the list. I added a debug.log to the start() method and it reports that MonsterKeys.Count == 2, then I Debug.Log the same thing from inside the PlaceItem function and the result is 0. Code for the entire class is below:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MonsterManager : MonoBehaviour {
private List<RogueMonster> Monsters;
private List<RogueMonster> ActiveMonsters;
private List<string> MonsterKeys;
public GameObject Slime;
public GameObject Alien;
private Dictionary<string, GameObject> AvailableMonsters;
private Dictionary<string, Dictionary<string, int>> MonsterStats;
private void Awake()
{
DontDestroyOnLoad(gameObject);
Monsters = new List<RogueMonster>();
AvailableMonsters = GetAvailableMonsters();
MonsterKeys = new List<string>();
foreach (KeyValuePair<string, GameObject> kvp in AvailableMonsters)
{
MonsterKeys.Add(kvp.Key);
}
Debug.Log(MonsterKeys.Count.ToString());
Debug.Log(MonsterKeys.Count.ToString());
MonsterStats = SetMonsterStats();
}
private void Update()
{
Debug.Log(MonsterKeys.Count.ToString());
}
private Dictionary<string, GameObject> GetAvailableMonsters()
{
return new Dictionary<string, GameObject>
{
{ "Alien", Alien },
{ "Slime", Slime }
};
}
private Dictionary<string, Dictionary<string, int>> SetMonsterStats()
{
return new Dictionary<string, Dictionary<string, int>>
{
{ "Slime", new Dictionary<string,int>
{
{"hp", 2 },
{"melee", 1 },
{"magic", 0 },
{"ranged", 0 },
{"def", 0 }
}
},
{ "Alien", new Dictionary<string, int>
{
{"hp", 2 },
{"melee", 1 },
{"magic", 0 },
{"ranged", 0 },
{"def", 0 }
}
},
};
}
public void GenerateMonsters(List<Rect> rooms, int mCount)
{
foreach(Rect r in rooms)
{
PlaceMonsters(r, mCount);
}
}
private void PlaceMonsters(Rect r, int mCount)
{
int monsterCount = Random.Range(1, mCount);
for(int m = 0; m < monsterCount; m++)
{
bool placed = false;
while (!placed)
{
int x = Random.Range(r.x1, r.x2);
int y = Random.Range(r.y1, r.y2);
int i = Random.Range(0, MonsterKeys.Count);
string mType = MonsterKeys*;*
GameObject monster = Instantiate(AvailableMonsters[mType], new Vector3(x, y, 3), Quaternion.identity);
RogueMonster rm = monster.GetComponent();
Combatant c = monster.GetComponent();
rm.SetCombatValues(MonsterStats[mType]);
rm.Name = mType;
Monsters.Add(rm);
CombatManager.AddCombatantToList(c);
}
}
}
}
EDIT: When I move my Dictionary and List initialization the GenerateMonsters method, everything works fine. For some reason, initializing in the Awake method isn’t persisting.