how to repeat randomize questions in a list?

I have a quiz game with randomize quiestions.
My problem is after the first game ended and I restarted the game, the index of random questions didn’t restarted. The remaining questions is only the one it displays so the error becomes out of range because all of my questions has been used up. Like I have 15 questions prepared, then the first time I play the game it uses 10 questions and when I play again only the remaining 5 it will display. How can I make it repeat other questions to reused again?


This is my code for my Game Controller.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using TMPro;
using UnityEngine.SceneManagement;
using System.Linq;

public class lf_idGameController : MonoBehaviour {

public TMP_Text questionText;
public TMP_Text isCorrectText;
public TMP_Text scoreText;
public TMP_Text resultText;
public TMP_InputField InputTextAnswer;

public GameObject questionDisplay;
public GameObject resultDisplay;
public AudioSource BGMResult;

private lf_idAnswerData IDanswerData;
private lf_idDataController dController;
private lf_idRoundData currentRound;

private lf_idQuestionData[] questionPool;
private static List<lf_idQuestionData> unansweredQuestions;
private lf_idQuestionData currentQuestion;

bool isRoundActive;
private int qIndex;
private int playerScore;
private int qCount;

void Start () {

	isCorrectText.text = "";
	
	dController = FindObjectOfType<lf_idDataController> ();
	currentRound = dController.ID_getCurrentRoundData ();
	questionPool = currentRound.questions;

	playerScore = 0;
	qIndex = 0;

	if (unansweredQuestions == null || unansweredQuestions.Count == 0) {

		unansweredQuestions = questionPool.ToList<lf_idQuestionData> ();
	}

	ShowQuestion ();
	//SetCurrentQuestion ();
	isRoundActive = true;
}

private void ShowQuestion()
{

	qIndex = Random.Range (0, unansweredQuestions.Count);
	currentQuestion = unansweredQuestions [qIndex];
	//		QuestionData questionData = questionPool [qIndex];
	questionText.text = currentQuestion.questionText;

	unansweredQuestions.RemoveAt (qIndex);

}

public void AnswerButtonClicked(string answerText)
{

	if (answerText == currentQuestion.answer.answerText ) {
		playerScore += currentRound.points;
		scoreText.text = "Score: " + playerScore.ToString ();
		StartCoroutine ("Correct");
	}else{
		StartCoroutine ("Wrong");
	}

	InputTextAnswer.text = "";

	if (playerScore >= 1 && playerScore <=5) {
		resultText.text = "Result: GOOD!";
		BGMResult.clip = Resources.Load<AudioClip> ("Sounds/ResultPassed");
	} else if (playerScore >= 6 && playerScore <= 9) {
		resultText.text = "Result: VERY GOOD!";
		BGMResult.clip = Resources.Load<AudioClip> ("Sounds/ResultPassed");
	} else if (playerScore == 10) {
		resultText.text = "Result: PERFECT!";
		BGMResult.clip = Resources.Load<AudioClip> ("Sounds/ResultPassed");
	} else if (playerScore == 0) {
		resultText.text = "Result: REVIEW!";
		BGMResult.clip = Resources.Load<AudioClip> ("Sounds/ResultFailed");
	}

	if (questionPool.Length > qIndex + 1) {

		qIndex++;
		ShowQuestion ();

		if (qCount == 10)//(unansweredQuestions.Count == 0)
			EndRound ();	
	}

}

public void EndRound()
{

	isRoundActive = false;

	questionDisplay.SetActive (false);
	resultDisplay.SetActive (true);

}

public void ReturnToMenu()
{
	SceneManager.LoadScene ("Main");
}

IEnumerator Correct()
{
	qCount = qCount + 1;
	isCorrectText.text = "Correct!";
	yield return new WaitForSeconds (1);
	isCorrectText.text = "";
}

IEnumerator Wrong()
{
	qCount = qCount + 1;
	isCorrectText.text = "Wrong!";
	yield return new WaitForSeconds (1);
	isCorrectText.text = "";
}

}


Here is the error I get.

ArgumentOutOfRangeException: Argument is out of range.
Parameter name: index
System.Collections.Generic.List1[lf_idQuestionData].get_Item (Int32 index) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Collections.Generic/List.cs:633) lf_idGameController.ShowQuestion () (at Assets/Script/LFQuiz/LFQuiz_ID/lf_idGameController.cs:63) lf_idGameController.AnswerButtonClicked (System.String answerText) (at Assets/Script/LFQuiz/LFQuiz_ID/lf_idGameController.cs:106) UnityEngine.Events.InvokableCall1[System.String].Invoke (System.Object args) (at C:/buildslave/unity/build/Runtime/Export/UnityEvent.cs:189)
UnityEngine.Events.InvokableCallList.Invoke (System.Object parameters) (at C:/buildslave/unity/build/Runtime/Export/UnityEvent.cs:637)
UnityEngine.Events.UnityEventBase.Invoke (System.Object parameters) (at C:/buildslave/unity/build/Runtime/Export/UnityEvent.cs:773)
UnityEngine.Events.UnityEvent1[T0].Invoke (.T0 arg0) (at C:/buildslave/unity/build/Runtime/Export/UnityEvent_1.cs:53) TMPro.TMP_InputField.SendOnEndEdit () TMPro.TMP_InputField.DeactivateInputField () TMPro.TMP_InputField.OnDeselect (UnityEngine.EventSystems.BaseEventData eventData) UnityEngine.EventSystems.ExecuteEvents.Execute (IDeselectHandler handler, UnityEngine.EventSystems.BaseEventData eventData) (at C:/buildslave/unity/build/Extensions/guisystem/UnityEngine.UI/EventSystem/ExecuteEvents.cs:113) UnityEngine.EventSystems.ExecuteEvents.Execute[IDeselectHandler] (UnityEngine.GameObject target, UnityEngine.EventSystems.BaseEventData eventData, UnityEngine.EventSystems.EventFunction1 functor) (at C:/buildslave/unity/build/Extensions/guisystem/UnityEngine.UI/EventSystem/ExecuteEvents.cs:261)
UnityEngine.EventSystems.EventSystem:Update()

Store the full list of Questions in a separate list that is never edited. Then, at the beginning of a new game, set the list of questions that are used to the full list, so it will now be restored from that list, and will always have all questions on a new game.

I think your problem is that unansweredQuestions list is static.

Change

     if (unansweredQuestions == null || unansweredQuestions.Count == 0) {
         unansweredQuestions = questionPool.ToList<lf_idQuestionData> ();
     }

To

if (unansweredQuestions.Count < questionPool.Length)
{
    unansweredQuestions = questionPool.ToList<lf_idQuestionData>();
}

The easiest way to manage your questions is to make scriptable objects for each question, so you can easily edit them in the editor. Put them all in a resource folder or reference in a list from your game controller script. in Start() you may also copy all questions into a new dynamic “unanswered” Queue randomizing the order at that point, then you can Dequeue() questions when needed. I can provide a code sample if you are interested…


UPDATE:
Here it is:

using UnityEngine;

[CreateAssetMenu(menuName ="Questions/Question", fileName ="Question")]
public class QuestionAsset : ScriptableObject
{
    public int questionId;
    public string questionText;
    public string answerText;
    // other staff...
}


using System.Collections.Generic;
using UnityEngine;

[CreateAssetMenu(menuName = "Questions/Questions collection", fileName = "Questions collection")]
public class QuestionCollectionAsset : ScriptableObject
{
    public List<QuestionAsset> questionsAssetsList;
}



using System.Collections.Generic;
using UnityEngine;

public class QuestionManager : MonoBehaviour
{
    public QuestionCollectionAsset questionCollection;
    public Queue<QuestionAsset> randomizedQuestionsQueue;

    // Start is called before the first frame update
    void Start()
    {
        ResetQuestions();
    }

    public void ResetQuestions()
    {
        randomizedQuestionsQueue = GenerateQuestionsQueue(questionCollection);
    }

    private Queue<QuestionAsset> GenerateQuestionsQueue(QuestionCollectionAsset questionCollection)
    {
        // shuffeling temporary list
        var shuffledList = new List<QuestionAsset>(questionCollection.questionsAssetsList);
        for (int i = 0; i < shuffledList.Count; i++)
        {
            QuestionAsset temp = shuffledList*;*

int randomIndex = Random.Range(i, shuffledList.Count);
shuffledList = shuffledList[randomIndex];
shuffledList[randomIndex] = temp;
}

// create a queue from shuffeled list
return new Queue(shuffledList);
}

public void ShowNextQuestion()
{
if(randomizedQuestionsQueue != null && randomizedQuestionsQueue.Count > 0)
{
QuestionAsset q = randomizedQuestionsQueue.Dequeue();
DisplayQuestion(q);
} else
{
Debug.Log(“Out of questions”);
}
}

private void DisplayQuestion(QuestionAsset q)
{
Debug.Log(q.questionId + ": " + q.questionText);
}

[ContextMenu(“Test”)] // This allows launching the folllofing method from inspector component dropdown menu
public void Test()
{
ResetQuestions();
int numQuestions = randomizedQuestionsQueue.Count;
while (numQuestions > 0) {
ShowNextQuestion();
numQuestions–;
}

}
}