Hello my problem is exactly the thread name. This error command box shows me everytime I try to play my quiz game after 3 rounds. The quiz is basically guessing japanese symbols and every odd round you have to convert symbol to romaji and every even round you have to convert word to Hiragana. I paused the game after every round and found out that after 3rd round answered, it just deletes my list of Romaji and of course without list of possible questions, it can't create new one. Code (CSharp): gm.currentQuestion = Random.Range(0, 45); yield return new WaitForSeconds(2f); gm.QuestionText.text = gm.Hiragana[gm.currentQuestion] + "\nConvert To Romaji"; randomButton = Random.Range(0, 3); //Random Number where will be correct answer gm.ButtonText[randomButton].text = gm.Romaji[gm.currentQuestion]; //Write correct answer to button[corresponding to randomButton] AnswerIndex = gm.Romaji[gm.currentQuestion]; //Write to string variable current correct answer gm.Romaji.RemoveAt(gm.currentQuestion); //Remove answer from list of all Romaji symbols randomSymbol1 = Random.Range(0, 44); //Choose random number corresponding to Romaji symbol from list gm.ButtonText[0].text = gm.Romaji[randomSymbol1]; //Write symbol to button gm.Romaji.RemoveAt(randomSymbol1); //Remove symbol from list of all Romaji symbols randomSymbol2 = Random.Range(0, 43); gm.ButtonText[1].text = gm.Romaji[randomSymbol2]; gm.Romaji.RemoveAt(randomSymbol2); randomSymbol3 = Random.Range(0, 42); gm.ButtonText[2].text = gm.Romaji[randomSymbol3]; gm.Romaji.RemoveAt(randomSymbol3); randomSymbol4 = Random.Range(0, 41); gm.ButtonText[3].text = gm.Romaji[randomSymbol4]; gm.Romaji.RemoveAt(randomSymbol4); gm.ButtonText[randomButton].text = AnswerIndex; //Rewrite correct answer to button chosen in the beginning gm.Romaji.Clear(); //Clear the whole Romaji list gm.Romaji = gm.RomajiBackUp; //Replace cleared Romaji list for RomajiBackUp list Romaji list and RomajiBackUp list are in the beginning the same length and content but after removing symbols from Romaji list I have to rewrite it with the back up one, because the symbols have to be on the exact element number it was on the beginning. I know this looks kinda dumb which is why I want a help from you. How to solve this error? And if possible, how can I make the code easier or not buggy like now. PS: The code is cut from IEnumerator because other code chunks in it are not important
ArgumentOutOfRange usually means that you are trying to access an element in an array or a list with an index that is either higher than the maximum or less than 0. For example if I declare an array like this int[] array1 = new int[5]; then I can write array1[1]=5 or array1[4]=0, but If I try to assign a value to array1[5] or array1[-1] then I will get an error. First thing is to look at what line the error occurs on. What's going on there?
This error basically means that you have tried to access an item in an array outside of what the array allows - i.e. item 5 of a 3-item array. You're using a TON of arrays here, so the error could be at any one of the 14 array-accessing lines of code in this segment. In general, you should copy and paste the full error message, as it includes the line number of the error, though since you only included a portion of the script that wouldn't have helped. More to the point, any single one of the array uses here could be the culprit, because you're not using any safeguards on your array indices which would protect against these errors. First, is this pattern: Code (csharp): randomSymbol1 = Random.Range(0, 44); //Choose random number corresponding to Romaji symbol from list ... = gm.Romaji[randomSymbol1]; As written, we have no guarantee that randomSymbol1 is actually within the size of the gm.Romaji array. If you're off by even one, you'll get this problem. This is a safer way to access a random item from an array, because you 100% know the index will be a valid one: Code (csharp): randomSymbol = Random.Range(0,gm.Romaji.Count); //or .Length if it were a regular array like this[]. You can do basically the same thing on line 5. And then there's this pattern Code (csharp): gm.ButtonText[0].text = .... Again, there are no safeguards here to ensure that any of these indices are within the bounds of the gm.ButtonText array. In this case, you're doing this over and over, once with each item in the list, and there's a way to ensure that the code gets called exactly once for each item in this array: a for loop. And if we combine this within the advice from above, we don't need our 44, 43, 42 numbers - the .Count will update itself. And that means that all those chunks are near identical, perfect for a loop: Code (csharp): for (int i=0;i<gm.ButtonText.Count; i++) { //again, use .Length if ButtonText is a builtin array randomSymbol = Random.Range(0, gm.Romaji.Count); gm.ButtonText[i].text = gm.Romaji[randomSymbol]; gm.Romaji.RemoveAt(randomSymbol); }
I think the error occurs at the 28th line when I try to clear the list and then I want to overwrite it with back up list, because when I was testing it while running, both lists had been cleared so then when it wanted to reach for an element, it couldn't because there were no elements to choose from.
Thank you, I will definitely use this loop, but how can I bring Romaji list back to its original form? I try it in the 28th line with clearing it and then overwriting it with identical back up list but I think that's where it stops working. (I think it somehow clear both lists, not just the Romaji one)
That doesn't really make sense because there is no indexer on that line. The error message in the console should tell you exactly what line the error is actually happening on, though.
Ah, that'll do it. You need to copy the array. Both variables are pointing to the same object, so removing objects from the list means both variables will see the change. You need to actually copy the array, which IIRC you can do by feeding the old list into the new one's constructor: Code (csharp): gm.RomajiBackup = new List<whatever>(gm.Romaji);