Reputation: 47
I am really new to coding and I have run into my first problem...4 hours after looking at it and I realise I probably need some help.
The code is for 4 buttons, all of which have a very similar code (in fact almost identical except for the ID variable), yet 2 of them say 'argumentoutofrangeexception index' when loaded, despite the index being the same. (or so I think)
I have linked below the code for one of the not working buttons and one of the other buttons which does work + the test control:
NOT WORKING BUTTON
public class Answer3script : MonoBehaviour {
List<string> thirdchoice = new List<string>() { "first choice", "second choice", "third choice", "fourth", "fifth"};
public static string answerCorrect3 = "n";
void Update () {
if (Textcontrol.randQuestion > -1)
{
GetComponentInChildren<Text>().text = thirdchoice[Textcontrol.randQuestion];
}
if (Textcontrol.correctAnswer[Textcontrol.randQuestion] == Textcontrol.buttonSelected)
{
answerCorrect3 = "y";
}
}
}
WORKING BUTTON
public class Answer2script : MonoBehaviour {
List<string> secondchoice = new List<string>() { "first choice", "second choice", "third choice", "fourth choice", "fifth choice" };
public static string answerCorrect2 = "n";
void Update () {
if (Textcontrol.randQuestion > -1)
{
GetComponentInChildren<Text>().text = secondchoice[Textcontrol.randQuestion];
}
if (Textcontrol.correctAnswer[Textcontrol.randQuestion] == Textcontrol.buttonSelected)
{
answerCorrect2 = "y";
// if (answerCorrect2 == "y")
// {
// image.color = Color.green;
// }
}
}
}
TEXT CONTROL:
public class Textcontrol : MonoBehaviour {
List<string> questions = new List<string>() { "This is the first question", "second", "third", "fourth", "fifth" };
public static List<string> correctAnswer = new List<string>() { "Answer1", "Answer2", "Answer3", "Answer4", "Answer4" };
public static string buttonSelected;
public static string choiceSelected = "n";
public static int randQuestion=-1;
void Update () {
Image image = GameObject.Find("Answer1").GetComponent<Image>();
Image image2 = GameObject.Find("Answer2").GetComponent<Image>();
Image image3 = GameObject.Find("Answer3").GetComponent<Image>();
Image image4 = GameObject.Find("Answer4").GetComponent<Image>();
if (randQuestion == -1)
{
randQuestion = Random.Range(0, 5);
}
if (randQuestion > -1)
{
GetComponent<Text>().text = questions[randQuestion];
}
if (choiceSelected == "y")
{
choiceSelected = "n";
if (correctAnswer[randQuestion] == buttonSelected)
{
Debug.Log("Correct!");
}
}
}
}
Apologies for the really badly formatted code, I couldn't get it to work!
Upvotes: 0
Views: 138
Reputation: 90649
You have a race-condition here! The Update
of Answer3script
might be called before the one of Textcontrol
so randQuestion
could still have the default value -1
Instead of the first if
you could in both Update()
s simply do
private void Update()
{
// Check if Textcontrol values are set already
if (Textcontrol.randQuestion < 0 || Textcontrol.correctAnswer.Count < Textcontrol.randQuestion + 1 || Textcontrol.correctAnswer[Textcontrol.randQuestion] == null ) return;
// ....
}
so if the Textcontrol
is not ready yet than nothing happens.
The second condition || Textcontrol.correctAnswer.Count < Textcontrol.randQuestion + 1
makes sure the element with the index you are trying to access exists in the list.
Be aware that string
values can be null
! Therefore, the third condition || Textcontrol.correctAnswer[Textcontrol.randQuestion] == null
makes sure the value at the index you access actually has a valid value. If you want to avoid empty string (""
) as well, you caould also extend it to || string.IsNullOrEmpty(Textcontrol.correctAnswer[Textcontrol.randQuestion])
(I would prefer Solution 1)
Go to Edit
-> Project Settings
-> Script Execution Order
Click on the +
and add your two scripts Answer2Script
and Answer3Script
. You also can simply drag them (one by one onto the field). Without giving Textcontrol
a certain execution time here it will be executed in the DefualtTime block. So just make sure your two scripts are after the DefaultTime
. Than hit Apply
. This makes sure your two scripts always are executed after the Default Time
-> after Textcontrol
.
Upvotes: 1