Why does this simple script crash Unity, and how to do this properly?

Hello!

So I’m not very proficient in C#, and I can’t figure out how to find all the entries in a dictionary. So I decided to write this:

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

public class UpgradeManager : MonoBehaviour {

    public int Coins;
    public Text CoinText;
    public int SlotOneEquip;
    public int SlotTwoEquip;
    private Dictionary<string, int> UpgradeData;
    public int RandomIDInt;
    public int PopulatingList;

    //!!!! LINE 55 CRASHES UNITY
    void Start ()
    {
        UpgradeData = new Dictionary<string, int>();
        UpgradeData["10"] = 1;
        UpgradeData["100"] = 1;
        UpgradeData["1000"] = 1;
        UpgradeData["10000"] = 1;
        UpgradeData["100000"] = 1;
        UpgradeData["1000000"] = 1;
        UpgradeData["10000000"] = 1;
        UpgradeData["100000000"] = 1;
    }
   
    // Update is called once per frame
    void Update ()
    {
        //LATER REMOVE THIS
        //CoinText.text = Coins.ToString();
    }

    public void BuyUpgrade1()
    {
        //let's generate a random int
        //LATER fix so it can't try to create duplicates
        RandomIDInt = Random.Range(0, 999999999);
        //now add to dictionary... = to what upgrade you want
        UpgradeData.Add(RandomIDInt.ToString(), 1);
        //rob the player
        Coins -= 150;
        Debug.Log("Purchased upgrade");
    }

    public void Add500Coins()
    {
        Coins += 500;
        Debug.Log("500 coins added");
    }

    public void LookForUpgrades()
    {
        //this is what crashes Unity
        PopulatingList += 1;

        if (PopulatingList == 101)
        {
            Debug.Log("Everything finished in: " + Time.fixedDeltaTime);
        }
        if (UpgradeData.ContainsKey(PopulatingList.ToString()))
        {
            Debug.Log("Key " + PopulatingList + " found in " + Time.fixedDeltaTime);
            LookForUpgrades();
        }

        else
        {
            LookForUpgrades();
        }
    }
}

The idea of everything below line 55 was to look thru the dictionary and return all the existing items. Obviously this isn’t the way to do things, but I don’t know what else to do. However this script crashes Unity in about 20 seconds. This is so strange as all it’s doing is adding a number and looking thru a dictionary.

P.S. Please let me know how to do this the right way. I like to learn :slight_smile:

this is why it crashes unity

public void LookForUpgrades()
    {
        if (...)
        {
            LookForUpgrades();
        }
        else
        {
            LookForUpgrades();
        }
    }

infinite loop

Interesting, I didn’t even notice lol

So how can I continue searching for all the items without having the infinite loop?

Technically not an infinite loop, but recursion until you blow the stack. Each time you call LookForUpgrades the program pushes something on the stack (an area of memory sort of like a scratchpad where it remembers where it was so it can go back when the call is done) and since you do it over and over again, you eventually exceed the size allocated to the stack. This is a common problem with recursion (when a function calls itself over and over).

Probably you should just loop through the list inline:

foreach(KeyValuePair<string, int>kvp in UpgradeData)
{
    if(kvp.Key.Equals("1000")) 
    {
        // do something
    }
}

Thanks for all your replies. I was doing it a quite stupid way because all of my scripts aren’t finished yet. For now I’ve updated it to work better (for now). Later of course I’ll make a more efficient method once everything else is in place.

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

public class UpgradeManager : MonoBehaviour {

    public int Coins;
    public Text CoinText;
    public int SlotOneEquip;
    public int SlotTwoEquip;
    private Dictionary<string, int> UpgradeData;
    public int RandomIDInt;
    public int PopulatingList;

    //!!!! LINE 55 CRASHES UNITY
    void Start ()
    {
        UpgradeData = new Dictionary<string, int>();
        UpgradeData["10"] = 1;
        UpgradeData["20"] = 1;
        UpgradeData["50"] = 1;
    }
   
    // Update is called once per frame
    void Update ()
    {
        //LATER REMOVE THIS
        //CoinText.text = Coins.ToString();
        //LookForUpgrades();
    }

    public void BuyUpgrade1()
    {
        //let's generate a random int
        //LATER fix so it can't try to create duplicates
        //RandomIDInt = Random.Range(0, 1000);
        RandomIDInt = Random.Range(0, 100);
        if (UpgradeData.ContainsKey(RandomIDInt.ToString()))
        {
            Debug.Log("TryingAgain");
            BuyUpgrade1();
        }
        //now add to dictionary... = to what upgrade you want
        UpgradeData.Add(RandomIDInt.ToString(), 1);
        //rob the player
        Coins -= 150;
        Debug.Log("Purchased upgrade");
    }

    public void Add500Coins()
    {
        Coins += 500;
        Debug.Log("500 coins added");
    }

    public void LookForUpgrades()
    {
        //this is what crashes Unity
        PopulatingList += 1;
        if (PopulatingList == 200)
        {
            Debug.Log("Search Finished!");
        }
        if (UpgradeData.ContainsKey(PopulatingList.ToString()))
        {
            Debug.Log("Key " + PopulatingList + "found!");
        }

        if (PopulatingList <= 200)
        {
        }
    }

    IEnumerator KeepSearching()
    {
        yield return new WaitForSeconds(0.01f);
        LookForUpgrades();
    }
}