- Home /
How to randomize non-repaeting question?
Hi, I`m making a quiz game following official live training tutorial and I would like to set it up so that the questions are showing up randomly in that way that they are not repeating in the currentRound of quiz. I saw in comments of that tutorial that author said we could use Shuffle bag technique but that is a little bit too complicated to implement. Is there any other simpler way to do it? Here`s a script from that tutorial that contains ShowQuestion method:
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
using System.Collections.Generic;
public class GameController : MonoBehaviour
{
public SimpleObjectPool answerButtonObjectPool;
public Text questionText;
public Text scoreDisplay;
public Text timeRemainingDisplay;
public Transform answerButtonParent;
public GameObject questionDisplay;
public GameObject roundEndDisplay;
public Text highScoreDisplay;
private DataController dataController;
private RoundData currentRoundData;
private QuestionData[] questionPool;
private bool isRoundActive = false;
private float timeRemaining;
private int playerScore;
private int questionIndex;
private List<GameObject> answerButtonGameObjects = new List<GameObject>();
void Start()
{
dataController = FindObjectOfType<DataController>(); // Store a reference to the DataController so we can request the data we need for this round
currentRoundData = dataController.GetCurrentRoundData(); // Ask the DataController for the data for the current round. At the moment, we only have one round - but we could extend this
questionPool = currentRoundData.questions; // Take a copy of the questions so we could shuffle the pool or drop questions from it without affecting the original RoundData object
timeRemaining = currentRoundData.timeLimitInSeconds; // Set the time limit for this round based on the RoundData object
UpdateTimeRemainingDisplay();
playerScore = 0;
questionIndex = 0;
ShowQuestion();
isRoundActive = true;
}
void Update()
{
if (isRoundActive)
{
timeRemaining -= Time.deltaTime; // If the round is active, subtract the time since Update() was last called from timeRemaining
UpdateTimeRemainingDisplay();
if (timeRemaining <= 0f) // If timeRemaining is 0 or less, the round ends
{
EndRound();
}
}
}
void ShowQuestion()
{
RemoveAnswerButtons();
QuestionData questionData = questionPool[questionIndex]; // Get the QuestionData for the current question
questionText.text = questionData.questionText; // Update questionText with the correct text
for (int i = 0; i < questionData.answers.Length; i ++) // For every AnswerData in the current QuestionData...
{
GameObject answerButtonGameObject = answerButtonObjectPool.GetObject(); // Spawn an AnswerButton from the object pool
answerButtonGameObjects.Add(answerButtonGameObject);
answerButtonGameObject.transform.SetParent(answerButtonParent);
answerButtonGameObject.transform.localScale = Vector3.one;
AnswerButton answerButton = answerButtonGameObject.GetComponent<AnswerButton>();
answerButton.SetUp(questionData.answers[i]); // Pass the AnswerData to the AnswerButton so the AnswerButton knows what text to display and whether it is the correct answer
}
}
void RemoveAnswerButtons()
{
while (answerButtonGameObjects.Count > 0) // Return all spawned AnswerButtons to the object pool
{
answerButtonObjectPool.ReturnObject(answerButtonGameObjects[0]);
answerButtonGameObjects.RemoveAt(0);
}
}
public void AnswerButtonClicked(bool isCorrect)
{
if (isCorrect)
{
playerScore += currentRoundData.pointsAddedForCorrectAnswer; // If the AnswerButton that was clicked was the correct answer, add points
scoreDisplay.text = playerScore.ToString();
}
if(questionPool.Length > questionIndex + 1) // If there are more questions, show the next question
{
questionIndex++;
ShowQuestion();
}
else // If there are no more questions, the round ends
{
EndRound();
}
}
private void UpdateTimeRemainingDisplay()
{
timeRemainingDisplay.text = Mathf.Round(timeRemaining).ToString();
}
public void EndRound()
{
isRoundActive = false;
questionDisplay.SetActive(false);
roundEndDisplay.SetActive(true);
}
public void ReturnToMenu()
{
SceneManager.LoadScene("MenuScreen");
}
}
currentRoundData = dataController.GetCurrentRoundData();
// Ask the DataController for the data for the current round. At the moment, we only have one round - but we could extend this
I am also working with a similar game code, and need help with the above statement. I want to extend the above line to go to the next round. Can anyone help me with this please.
You could make a list and populate it with questions, call a random item and remove it when you're done.
Your answer