Quiz Game : Valid Question keep decreasing each time the game start.

Hi there I’m making a true false quiz game.
I have a problem regarding question index.


So there’s supposed to be 30 question stored for a level, and the 20 question appear randomly one by one. After answering the 20th question then the player win.


But here’s the problem. For example I start to try playing. The valid question is 30. Then I answer few question (for example 4). When I restart the game, the valid question is start from 26 instead of 30 again. Is there any way to fix it?


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
 
public class QuestionsData : MonoBehaviour
{
    public Questions questions;
 
    [SerializeField]
    private Text _questionText;
 
    public GameObject completeLevelUI;
 
    void Start()
    {
        AskQuestion();
    }
 
    public void AskQuestion()
    {
        if (CountValidQuestions() == 10)
        {
            _questionText.text = string.Empty;
            ClearQuestion();
            CompleteLevel();
            return;
        }
        var randomIndex = 0;
        do
        {
            randomIndex = UnityEngine.Random.Range(0, questions.questionsList.Count);
        }
        while (questions.questionsList[randomIndex].questioned == true);
 
        questions.currentQuestion = randomIndex;
        questions.questionsList[questions.currentQuestion].questioned = true;
        _questionText.text = questions.questionsList[questions.currentQuestion].question;
    }
 
    public void ClearQuestion()
    {
        foreach (var question in questions.questionsList)
        {
           question.questioned = false;
        }
    }
 
    private int CountValidQuestions()
    {
        int validQuestions = 0;
 
        foreach (var question in questions.questionsList)
        {
            if (question.questioned == false)
                validQuestions++;
        }
 
        Debug.Log("Question Left " + validQuestions);
        return validQuestions;
    }
 
    public void CompleteLevel()
    {
        completeLevelUI.SetActive(true);
    }
}

It looks like you’re just counting questions which haven’t been asked (which is probably right) and not resetting the value on restart. You’ll need to iterate over the questions and set each question in questions.questionsList to true.

I’d rename some of your variables too, questions should be the list of questions questions.questionsList has ambiguity.

Personally, I’d address the way you’re picking your questions and reset the array or available questions.
This is only pseudo and won’t tie up with your variable naming.

First create a list of all questions however you’re currently doing it, then duplicate that list at the start of the first round.

var availableQuestions = new List<Question>(allQuestions);

Remove the question from the list when it’s picked.

var index = Random.Range(0, availableQuestions.Count); //also ensure you haven't ran out of questions
var selectedQuestion = availableQuestions[index];
availableQuestions.Remove(selectedQuestion);

//display selectedQuestion

And separate out your functions to keep them concise as to what each does. e.g.

public Question PickQuestion() {}
public void AskQuestion(Question q) {}
public void DisplayQuestion() {}
public void RestartGame()

Thankyou for your suggestion.
So I make it like a question countdown like this :


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class QuestionLeft : MonoBehaviour
{
    public Text questionsleftText;
    private int questionsLeft;


    void Start()
    {
        questionsLeft  = 20;
        questionsleftText.text = questionsLeft.ToString();
    }


    public void MinQuestions()
    {
        questionsLeft -= 1;
        questionsleftText.text = questionsLeft.ToString();
    }

}

and then I make it in my game manager like this :


public void ShowResults(bool answer)
    {
        correctSprite.SetActive(questions.questionsList[questions.currentQuestion].isTrue == answer);
        incorrectSprite.SetActive(questions.questionsList[questions.currentQuestion].isTrue != answer);

        if (questions.questionsList[questions.currentQuestion].isTrue == answer)
        {
            questionLeft.MinQuestions();
            scores.AddScore();
            if (questions.questionsList[questions.currentQuestion].isTrue)
            {               
                trueAnswerText.text = "CORRECT!!";
                falseAnswerText.text = "WRONG:(";
            }
            else
            {
                trueAnswerText.text = "WRONG:(";
                falseAnswerText.text = "CORRECT!!";
            }
        }

        else
        {
            questionLeft.MinQuestions();
            scores.DeductScore();
        }

            trueButton.interactable = false;
            falseButton.interactable = false;

            StartCoroutine(ShowResult());   
    }

Then I put it on the game object and put the game object in the game manager than I try to play and it works. The countdown decreasing on every question like it supposed to do.


But the problem is when I change the game over condition. Before, it was like this :


if (CountValidQuestions() == 10)
         {
             _questionText.text = string.Empty;
             ClearQuestion();
             CompleteLevel();
             return;
         }

but then since I’m using the countdown, I change it to be like this :


 public QuestionLeft questionLeft;

public void AskQuestion()
    {
        if (questionLeft.questionsLeft() == 0)
        {
            _questionText.text = string.Empty;
            ClearQuestion();
            CompleteLevel();
            return;
        }

this happen instead :

Non-invocable member ‘QuestionLeft.questionsLeft’ cannot be used like a method.

Do you know any idea why?