Function runs fine the first time but crashes if I run it twice?
I have a function that runs fine the first time it executes at start but it crashes the second time I run it after an interaction. I suspect the issue may be related to for-loops similar to to the freezing described here but I think my function is just executing once. I also found this but even after 15 minutes nothing executed.
Here is the function:
public void ShuffleCards()
{
print("test");
//Choose Correct Dictionary
foreach (object key in RandomKey(initialSoundDictQueue).Take(1))
{
correctSoundDict = key.ToString();
}
//Choose Correct Card
foreach (object value in RandomValues(cardQueue).Take(1))
{
correctCard = (GameObject)value;
correctCard.AddComponent<CorrectCard>();
}
//Reveal Correct Card
foreach (object key in RandomKey(initialSoundDictQueue[correctSoundDict]).Take(1))
{
string stringKey = key.ToString();
correctObject = initialSoundDictQueue[correctSoundDict][stringKey];
Instantiate(correctObject, correctCard.transform.position, Quaternion.identity, correctCard.transform.GetChild(0));
TextMeshPro title = correctCard.transform.GetChild(1).GetComponent<TextMeshPro>();
string noSpaceTitle = stringKey.Replace(" ", string.Empty);
title.text = noSpaceTitle;
TextMeshPro subhead = correctCard.transform.GetChild(2).GetComponent<TextMeshPro>();
subhead.text = stringKey;
}
//Choose Incorrect Dictionary
foreach (object key in RandomKey(initialSoundDictQueue).Take(1))
{
incorrectSoundDict = key.ToString();
}
//Choose First Incorrect Card1
foreach (object value in RandomValues(cardQueue).Take(1))
{
incorrectCard1 = (GameObject)value;
}
;
//Reveal First Incorrect Card
foreach (object key in RandomKey(initialSoundDictQueue[incorrectSoundDict]).Take(1))
{
string stringKey = key.ToString();
incorrectObject1 = initialSoundDictQueue[incorrectSoundDict][stringKey];
Instantiate(incorrectObject1, incorrectCard1.transform.position, Quaternion.identity, incorrectCard1.transform.GetChild(0));
TextMeshPro title = incorrectCard1.transform.GetChild(1).GetComponent<TextMeshPro>();
string noSpaceTitle = stringKey.Replace(" ", string.Empty);
title.text = noSpaceTitle;
TextMeshPro subhead = incorrectCard1.transform.GetChild(2).GetComponent<TextMeshPro>();
subhead.text = stringKey;
}
//Choose Second Incorrect Card1
foreach (object value in RandomValues(cardQueue).Take(1))
{
incorrectCard2 = (GameObject)value;
}
//Reveal Second Incorrect Card
foreach (object key in RandomKey(initialSoundDictQueue[incorrectSoundDict]).Take(1))
{
string stringKey = key.ToString();
incorrectObject2 = initialSoundDictQueue[incorrectSoundDict][stringKey];
Instantiate(incorrectObject2, incorrectCard2.transform.position, Quaternion.identity, incorrectCard2.transform.GetChild(0));
TextMeshPro title = incorrectCard2.transform.GetChild(1).GetComponent<TextMeshPro>();
string noSpaceTitle = stringKey.Replace(" ", string.Empty);
title.text = noSpaceTitle;
TextMeshPro subhead = incorrectCard2.transform.GetChild(2).GetComponent<TextMeshPro>();
subhead.text = stringKey;
}
}
public IEnumerable<TValue> RandomValues<TKey, TValue>(IDictionary<TKey, TValue> dict)
{
System.Random rand = new System.Random();
List<TValue> values = Enumerable.ToList(dict.Values);
int size = dict.Count;
while (true)
{
TValue chosenValue = values[rand.Next(size)];
if (vetList.Contains(chosenValue.ToString()))
{
//print("Contains");
}
else
{
vetList.Add(chosenValue.ToString());
yield return chosenValue;
}
}
}
public IEnumerable<TKey> RandomKey<TKey, TValue>(IDictionary<TKey, TValue> keyQueue)
{
System.Random rand = new System.Random();
List<TKey> Keys = Enumerable.ToList(keyQueue.Keys);
int size = keyQueue.Count;
while (true)
{
TKey chosenKey = Keys[rand.Next(size)];
if (vetList.Contains(chosenKey.ToString()))
{
print("Contains");
}
else
{
vetList.Add(chosenKey.ToString());
yield return chosenKey;
}
}
}
This is where it freezes when I execute resetExercise() after interaction with a card. Test will print so I assume the for loop is what's freezing it? Apologies if the answer is obvious.
public void resetExercise () {
GameObject ShuffleObject = GameObject.Find("InitialSoundCardShuffler");
CardShuffler = ShuffleObject.GetComponent<InitialSoundCardShuffler>();
CardShuffler.initialSoundCounter++;
CardShuffler.progressBar.value = CardShuffler.CalculateProgress();
CardShuffler.ShuffleCards();
}
the number of calls to the random methods that are allowed before enter a infinite loop, strong depends of their respective dict size, what happen if you replace: in RandomValues()
while (true){
by
while (vetList.count < size)
and create a vetList$$anonymous$$
to hold the values generated in Random$$anonymous$$ey()
, also change inside the while
of Random$$anonymous$$ey()
:
while (vetList$$anonymous$$.count<size)
{
T$$anonymous$$ey chosen$$anonymous$$ey = $$anonymous$$eys[rand.Next(size)];
if (vetList$$anonymous$$.Contains(chosen$$anonymous$$ey.ToString()))
{
print("Contains");
}
else
{
vetList$$anonymous$$.Add(chosen$$anonymous$$ey.ToString());
yield return chosen$$anonymous$$ey;
}
}
if you still have cpu overloads, probably will need to change some desing, like verify if you need a script to check if a card is correct (maybe you store some values there, idk) otherwise, use a bool or change tag, or use a comparer inside a list of string, maybe you cannot do the comparision of all TValues already chosen on other, more efficient way?, you know, I dont have all the proyect so I can only make assumptions about how optimize it, you are on the field :)
Answer by Diesign · Feb 06, 2019 at 07:26 AM
It was because it ran out of inputs and went into an infinite loop while checking the vetlist and having not other dicts to choose from.
Your answer
![](https://koobas.hobune.stream/wayback/20220612191123im_/https://answers.unity.com/themes/thub/images/avi.jpg)
Follow this Question
Related Questions
Editor freezes after 'killing' an enemy but not every time 1 Answer
Unity freezes when I run this and I have no idea why, please help 0 Answers
If statement in for loop not working after fail 0 Answers
How to get a for loop to run once per coroutine? 1 Answer
Why does my game crash on my mobile when I try to load the scene with this interstitial ad script? 0 Answers