Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by mcNothing · Jul 02, 2018 at 03:58 AM · c#listdictionary

C# List Reported as Empty when called in method

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[i];
                 GameObject monster = Instantiate(AvailableMonsters[mType], new Vector3(x, y, 3), Quaternion.identity);
                 RogueMonster rm = monster.GetComponent<RogueMonster>();
                 Combatant c = monster.GetComponent<Combatant>();
                 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.

Comment
Add comment · Show 10
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image hexagonius · Jul 02, 2018 at 06:26 AM 0
Share

what line are you getting the error at?

avatar image mcNothing hexagonius · Jul 02, 2018 at 11:35 AM 0
Share

@hexagonius I get the error on line 89: string mType = $$anonymous$$onster$$anonymous$$eys[i];

avatar image Sonky108 · Jul 02, 2018 at 06:27 AM 0
Share

$$anonymous$$y first thought is you are trying to call Place$$anonymous$$onsters/Generate$$anonymous$$onsters before Awake happens. I assume that you are calling it form another script? If you call it from another script in Awake method it will be called in random order until you will change Script Execution Order.

If that is the case, first you should see error in the log and then $$anonymous$$onster$$anonymous$$eys.Count == 2

avatar image mcNothing Sonky108 · Jul 02, 2018 at 11:40 AM 0
Share

@Sonky108 Generate$$anonymous$$onsters is called by the map function after the tiles are placed. The map function is called by the game manager using the Scene$$anonymous$$anager.sceneloaded event. The game loads to a main menu, with a 'start game' button, I click that to load the next scene which calls the map generation function.

avatar image Sonky108 mcNothing · Jul 02, 2018 at 11:49 AM 0
Share

Can you confirm that Awake (from referenced instance) is called before that map function? Also you marked $$anonymous$$onster$$anonymous$$anager as DonDestroyOnLoad, so are you sure that you are referencing to correct instance of the object?

Show more comments
avatar image Shameness · Jul 02, 2018 at 06:40 AM 0
Share

See reference, you can't treat Dictionary like ordered array. See if fallowing q&a helps your issue. https://stackoverflow.com/questions/4227/accessing-a-dictionary-keys-key-through-a-numeric-index tl:dr: "Dictionary.$$anonymous$$eys does not implement a []-indexer", "mydict.$$anonymous$$eys.ElementAt(mydict.Count -1)"

avatar image mcNothing Shameness · Jul 02, 2018 at 11:44 AM 0
Share

@Shameness Yup, I know it's not possible to access the dictionary by index, so I am trying to get a List of the keys and accessing that list by index. The problem is that on Awake, the program reports that keys.count == 2, then when I access the same list on line 89, with keys[0] or keys[1], the index is out of range.

1 Reply

· Add your reply
  • Sort: 
avatar image
0

Answer by ShadyProductions · Jul 02, 2018 at 11:49 AM

You receive "Index out of range" so where you're trying to access MonsterKeys[i], i is actually out of the range of the list.

Over here you're missing index 0, so if you only have 1 monster you will already trigger this error. At:

 Random.Range(1, MonsterKeys.Count);

In the case you have more than one monster and receive this error, your list is simply not initialized before the method is called.


On a possible fix, you could lazy load it (which isn't as great for performance because this means it will load your data during the first time it accesses the property, but it should fix this issue.). I would advise to rather find the core problem where the list is not being initialized, and fix it there.

     private List<string> _monsterKeys;
     private List<string> MonsterKeys
     {
         get { return _monsterKeys ?? (_monsterKeys = AvailableMonsters.Keys.ToList()); }
     }
Comment
Add comment · Show 8 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image mcNothing · Jul 02, 2018 at 12:04 PM 0
Share

I changed the list initialization in the Awake() function to: $$anonymous$$onster$$anonymous$$eys = new List<string> {"Alien", "Slime"}; and still get the IndexError when calling it, even if I put in $$anonymous$$onster$$anonymous$$eys[0];

avatar image ShadyProductions mcNothing · Jul 02, 2018 at 12:26 PM 0
Share

That is because you call your method BEFORE awake gets called. Add your script to the script execution order settings, and make sure this script is called before the script that calls your method. Or use the lazy method. If you are certain that awake is called before then, Perhaps it might help to post the script where you call the method. So we can see how you get the reference to your monstermanager script.

avatar image mcNothing ShadyProductions · Jul 02, 2018 at 12:37 PM 0
Share

$$anonymous$$onster$$anonymous$$anager is Awake before the scene is loaded, and the scene loading is what triggers the call to Generate$$anonymous$$onsters. Changing Script Execution Order to put $$anonymous$$onster$$anonymous$$anager first doesn't fix the problem. If I initialize my dictionaries and lists in the Generate$$anonymous$$onsters method, there are no errors.

Show more comments

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

526 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Sorting a List of Dictionaries in C#? 4 Answers

A node in a childnode? 1 Answer

Runtime instantiation based on XML 1 Answer

IDictionary 1 Answer

Can be list stored in dictionary? 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges