How can I randomly create a number and then delete it to stop repeating

I am trying to create some code that randomly picks from 1 to 5 so it would come up with a result from 1 to 4 and once its randomly picked/generated I want to delete from the list therefore disabling repeating. Here is the code I have and the error I receive (Argument is out of range)

public class GameManager2 : MonoBehaviour
{

    public GameObject Question1, Question2, Question3;
   
    List<int> list = new List<int>();
    private int i, index;

	void Start ()
    {
        for (int n = 1; n < 5; n++)
        {
            list.Add(n);

        }

        CheckQuestion();
    }
	

	void Update ()
    {
        if (Input.GetKeyDown(KeyCode.UpArrow))
        {
            CheckQuestion();
        }

        if  (i == 1)
        {
           Question1.SetActive(true);
           Question2.SetActive(false);
           Question3.SetActive(false);
           
          

        }
       

        if (i == 2)
        {
            Question2.SetActive(true);
            Question1.SetActive(false);
            Question3.SetActive(false);
           

        }

        if (i == 3)
        {
            Question3.SetActive(true);
            Question1.SetActive(false);
            Question2.SetActive(false);
           

        }

	}

    void CheckQuestion()
    {

        index = Random.Range(0, list.Count - 1);
        i = list[index];
        Debug.Log(i);
        list.RemoveAt(index);

    }

There’s a bit of confusion I guess with your values starting at 1, but indices starting at 0.

int Random.Range() never returns the max value, so if you List contains 1, 2, 3, 4, and you want a random number from that list, you can use this :

index = Random.Range(0, list.Count);

Which will return a value between 0 and 3, mapping to the table containing 1 to 4.

Otherwise, Count -1 will eventually return -1 when the list is empty, hence your issue I guess.

Also, it’s unrelated, but you can save yourself some complexity with the if statements by simply doing this :

Question1.SetActive(i == 1);
Question2.SetActive(i == 2);
Question3.SetActive(i == 3);

Hope this helps.

public GameObject Questions;
private List QuestionIndices ;

void Start ()
{
    if( Questions.Length == 0 )
    {
        Debug.LogError("No question provided!");
        enabled = false ;
        return ;
    }
    PickQuestion( PickQuestionIndex() );
}

void Update ()
{
    if (Input.GetKeyDown(KeyCode.UpArrow))
    {
        PickQuestion( PickQuestionIndex() );
    }
}

private void FillQuestionIndices()
{
    if( QuestionIndices == null )
        QuestionIndices = new List<int>(Questions.Length);

    for( int i = 0 ; i < Questions.Length ; ++i )
        QuestionIndices.Add( i ) ;
}

private void PickQuestion( int questionIndex )
{
    for( int i = 0 ; i < Questions.Length ; ++i )
        Questions*.SetActive( false ) ;*

if( questionIndex >= 0 && questionIndex && < Questions.Length )
Questions[questionIndex].SetActive( true ) ;
}

private int PickQuestionIndex()
{
if( QuestionIndices.Count == 0 )
FillQuestionIndices();

int listIndex = Random.Range(0, QuestionIndices.Count) ;
int questionIndex = QuestionIndices[listIndex];
QuestionIndices.RemoveAt(listIndex);
return questionIndex ;
}

Here is something I quickly made - Just link your question objects into the list:


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


public class Questions : MonoBehaviour
{
    [SerializeField] List<GameObject> questionObjects;

    List<GameObject> questionCopies;
    GameObject currentQuestion;


    void Awake()
    {
        questionCopies = new List<GameObject>(questionObjects);
        HideAllQuestions();
    }


    void Update()
    {
        if (Input.GetKeyDown(KeyCode.UpArrow))
        {
            GetQuestion();
        }
    }


    void GetQuestion()
    {
        // If we have questions, show one - if not, hide them all
        if (questionCopies.Count > 0)
        {
            GameObject newQuestion = questionCopies[Random.Range(0, questionCopies.Count)];
            DisplayQuestion(newQuestion);

            // Save the new current
            currentQuestion = newQuestion;

            // Remove so we don't get it again
            questionCopies.Remove(currentQuestion);
        }
        else
        {
            HideCurrentQuestion();
        }
    }


    void DisplayQuestion(GameObject question)
    {
        // Hide them all
        HideCurrentQuestion();

        // Show the new one
        question.SetActive(true);
    }


    void HideCurrentQuestion()
    {
        if (currentQuestion != null)
        {
            currentQuestion.SetActive(false);
        }
    }

    
    /// <summary>
    /// Turn them off in case they were on in the editor
    /// </summary>
    void HideAllQuestions()
    {
        for (int i = 0; i < questionCopies.Count; i++)
        {
            questionCopies*.SetActive(false);*

}
}
}