(I posted a very similar question here recently and the response I received was helpful. But I have been advised to start a new question, and here it is.)
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 the updated relevant sections of what I've coded so far:
1) The REVISED custom class:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using System.Linq; // LINQ (Language Integrated Query). The most common uses for LINQ statements tend to be sorting, searching, and filtering (though there’s plenty more you can do with it).
using System.IO;
// ******************************************************************
// See: https://gamedev.stackexchange.com/questions/166759/trying-to-load-json-questions-and-answers-into-a-multiple-choice-quiz-game-in-u
[System.Serializable]
public class QuestionCollection
{
public QuestionChoicesAnswerHintExplanation[] questions;
}
// ******************************************************************
[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 hint;
public string explanation;
}
2) From the REVISED GameController:
public QuestionCollection questionCollection; // See: https://gamedev.stackexchange.com/questions/166759/trying-to-load-json-questions-and-answers-into-a-multiple-choice-quiz-game-in-u
public QuestionChoicesAnswerHintExplanation[] questions; // This is the fixed size array of the questions, answer choices, answers, hints, and explanations.
private static List<QuestionChoicesAnswerHintExplanation> 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 QuestionChoicesAnswerHintExplanation currentQuestion; // The current question drawn at random.
private int randomIndex; // the index used to pick the random question.
string path; // The path to the .json file storing the questions, answer choices, correct answer index, hints, explanations.
string jsonString; // The contents of the .json file.
In the REVISED Start() in the GameController:
path = Application.streamingAssetsPath + "/questionsAndAnswers.json";
jsonString = File.ReadAllText(path);
questionCollection = JsonUtility.FromJson<QuestionCollection>(jsonString); // questionCollection contains an array of question-answer choices-answer-hint-explanation objects
questions = questionCollection.questions;
//questions = JsonUtility.FromJson<QuestionChoicesAnswerExplanation[]>(jsonString);
Debug.LogWarning("questionCollection:");
Debug.LogWarning(questionCollection);
Debug.LogWarning("Questions:");
Debug.LogWarning(questions);
if (questionsCopy == null || questionsCopy.Count == 0) // A list with zero elements isn't always null.
{
// questionsCopy = questions.ToList<QuestionChoicesAnswerExplanation>(); // <---- That was incorrect.
questionsCopy = questions.ToList<QuestionChoicesAnswerHintExplanation>();
Debug.LogWarning("questionsCopy:");
Debug.LogWarning(questionsCopy);
Debug.LogWarning("questionsCopy.Count:");
Debug.LogWarning(questionsCopy.Count);
Debug.LogWarning("questionsCopy[0]:");
Debug.LogWarning(questionsCopy[0]);
Debug.LogWarning("questionsCopy[1]:");
Debug.LogWarning(questionsCopy[1]);
Debug.LogWarning("questionsCopy[2]:");
Debug.LogWarning(questionsCopy[2]);
}
PickRandomQuestion();
Further down the GameController, here is the REVISED PickRandomQuestion():
public void PickRandomQuestion()
{
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,
"hint": "Hint: Trinculo is stranded on an island.",
"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,
"hint": "Hint: This character is very talkative.",
"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,
"hint": "Hint: This play is a comedy.",
"explanation": "'The Comedy of Errors.'"
}
]
}
This is not working, however. In the console, I am getting correct values for questionsCopy.Count and for randomIndex. But I am getting null values for questionsCopy[0], questionsCopy1, and questionsCopy[2]. I would appreciate any helpful advice. Thanks.