I am developing a Unity game which includes a multiple-choice quiz.
I've placed what I believe is a properly-formatted .json file (the quiz question, four answer choices, the correct answer, and an explanation for the answer) (which I checked with a .json formatter) in the StreamingAssets folder in the Unity project. I've created a custom class for the question, the four answer choices, the correct answer and the explanation of the answer.
I am trying to load the entire contents of the .json file into an array, "questions," then copy that array into another array, "questionsCopy." To avoid repeating questions, as a question is used during the gameplay, I will remove it (and its corresponding answer choices, correct answer and explanation) from the questionsCopy array. (I have not yet developed the GUI to show the question, answer choices and eventually the correct answer and its explanation.)
Here are relevant sections of what I've coded so far:
1) The custom class:
// This is the custom class:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[System.Serializable]
public class QuestionChoicesAnswerHintExplanation : MonoBehaviour {
public string[] question; // An array of strings (rather than just a string) so that line spacing, which doesn't play well with .json, could be preserved
public string[] answerChoices;
public int correctAnswerIndex;
public string explanation;
}
2) From the GameController:
public QuestionChoicesAnswerExplanation[] questions; // This is the fixed size array of the questions, answer choices, answers, and explanations.
private static List questionsCopy; // This is the resizeable list (originally a copy of the array). The size of this list will diminish as we remove items after presenting each question.
private QuestionChoicesAnswerExplanation currentQuestion;
string path; // The path to the .json file storing the questions, answer choices, correct answer index, explanations.
string jsonString; // The contents of the .json file.
In the Start() in the GameController:
path = Application.streamingAssetsPath + "/questionsAndAnswers.json";
jsonString = File.ReadAllText(path);
questions = JsonUtility.FromJson(jsonString);
// Debug.LogWarning("Questions:");
Debug.LogWarning(questions);
if (questionsCopy == null || questionsCopy.Count == 0) // A list with zero elements isn't always null.
{
questionsCopy = questions.ToList();
}
PickRandomQuestion();
Further down in the GameController:
public void PickRandomQuestion()
{
int randomIndex = Random.Range(0, questionsCopy.Count);
currentQuestion = questionsCopy[randomIndex];
questionsCopy.RemoveAt(randomIndex);
}
3) Here are the contents of the .json file in the StreamingAssets folder:
{
"questions":
[
{
"question": ["Trinculo admits 'I have been in such a pickle...' in this comedy:"],
"answerChoices": ["'The Tempest'", "'Henry 4, Part 1'", "'Henry 5'", "'The Merry Wives of Windsor'"],
"correctAnswerIndex": 0,
"explanation": "'Henry 4, Part 1,' and 'Henry 5, are both histories. To be in 'a pickle' usually means to be in a quandary. A broader view of this passage reveals Trinculo to be drunk: \n\nAlonso: \nAnd Trinculo is reeling ripe: where should they \nFind this grand liquor that hath gilded 'em? \nHow camest thou in this pickle? \n\nTrinculo: \nI have been in such a pickle since I \nsaw you last that, I fear me, will never out of \nmy bones: I shall not fear fly-blowing.' \n\n'The Tempest' 5.1."
},
{
"question": ["In 'Hamlet,' this character remarks: 'Neither a borrower nor a lender be; \nFor loan oft loses both itself and friend, \nAnd borrowing dulls the edge of husbandry. \nThis above all: to thine own self be true,\nAnd it must follow, as the night the day,\nThou canst not then be false to any man:'"],
"answerChoices": ["Fortinbras", "Gertrude", "Polonius", "The Ghost of Hamlet's Father"],
"correctAnswerIndex": 2,
"explanation": "The verbose Polonius is speaking to his son Laertes. 'Hamlet' 1.3."
},
{
"question": ["Roger Daltrey, well into his career with The Who, played the roles for both Dromios, the twin servants, in a 1983 BBC production of:"],
"answerChoices": ["'King John'", "'King Lear'", "'Coriolanus'", "'The Comedy of Errors'"],
"correctAnswerIndex": 3,
"explanation": "'The Comedy of Errors.'"
}
]
}
BUT I'm getting an error:
ArgumentOutOfRangeException: Argument is out of range. Parameter name: index
Parameter name: index System.Collections.Generic.List`1[QuestionChoicesAnswerExplanation].get_Item (Int32 index) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Collections.Generic/List.cs:633) GameController.PickRandomQuestion () (at Assets/Scripts/Managers/GameController.cs:741) GameController.Start () (at Assets/Scripts/Managers/GameController.cs:99)
The error message points to problems (GameController.cs:741 and GameController.cs:99), but I don't see what's wrong there. I am UNSURE about the message regarding line 633.
And the Debug.Logwarning yields this:
QuestionChoicesAnswerExplanation[] UnityEngine.Debug:LogWarning(Object) GameController:Start() (at Assets/Scripts/Managers/GameController.cs:92)
What need I do to fix this? Thank you.