简体   繁体   中英

Unity: Remove The selected object from random.range

I have a Quiz game with multiple choices. I Want to show random question however sometimes the same Questions is being picked more than once. I want to remove the selected questions out of my list so it doesn't get picked anymore..

This is the Game Manager that shows my question's ** Check the ShowQuestion Function there where i do my random. i basically want when a question is picked to not show again

public class GameController : MonoBehaviour {

private dataController DataController;
private roundData currentRoundData;
// QUestions that we will be working with in this round
private questionData[] questionPool;
private List<GameObject> answerButtonGameobjects = new List<GameObject>();

private List<GameObject> QuestionGameobjects = new List<GameObject>();


[Header("OTHER")]
public SimpleObjectPool answerButtonObjectPool;
public Transform answerButtonParent;


[Tooltip("Variables")]
// is the game going? 
private bool isRoundActive;
private float timerRemaing;
// What number question we are on
private int questionIndex;
private int questionNumber = 1;
private int totalQuestions;



[Header("UI")]
[Header("TEXT ")]
public Text questionText;
public Text scoreDisplayText;
public Text timeRemainingDisplayText;
public Text highScoreText;
public Text questionIndexText;

void Start () {

    DataController = FindObjectOfType<dataController>();

    currentRoundData = DataController.getCurrentRoundData();



    // stores our questions
    questionPool = currentRoundData.questions;

    timerRemaing = currentRoundData.timeLimitInSeconds;

    questionIndex = 0;

   totalQuestions = 10;


    ShowQuestion();

}

// Show our 1st question
private void ShowQuestion()
{
    RemoveAnsweredButtons();


    // Hold current question data from our pool
   questionData QuestionData = questionPool[Random.Range(0, totalQuestions)];

    questionText.text = QuestionData.questionText;

    for (int i = 0; i < QuestionData.answers.Length; i++)
    {
        GameObject answerButtonGameobject = answerButtonObjectPool.GetObject();
        answerButtonGameobject.transform.SetParent(answerButtonParent);
        answerButtonGameobjects.Add(answerButtonGameobject);

        AnswerButton answerButton = answerButtonGameobject.GetComponent<AnswerButton>();
        answerButton.Setup(QuestionData.answers[i]);
    }


}

/// <summary>
/// Removes the old answers button before we display new ones.
/// </summary>
private void RemoveAnsweredButtons()
{
    while (answerButtonGameobjects.Count > 0)
    {
        answerButtonObjectPool.ReturnObject(answerButtonGameobjects[0]);
        answerButtonGameobjects.RemoveAt(0);
    }


}




private void UpdateQuestionIndex()
{
    questionIndex++;

    questionNumber++;
    questionIndexText.text = "Question  " + (questionNumber.ToString()) +  " out of 10";
}



}

The Questions and Answers are being generated using a Simple pool system that was taken from Unity Site.

Here's the pooling class

using UnityEngine;
using System.Collections.Generic;

// A very simple object pooling class
 public class SimpleObjectPool : MonoBehaviour
{
// the prefab that this object pool returns instances of
public GameObject prefab;
// collection of currently inactive instances of the prefab
private Stack<GameObject> inactiveInstances = new Stack<GameObject>();

// Returns an instance of the prefab
public GameObject GetObject() 
{
    GameObject spawnedGameObject;

    // if there is an inactive instance of the prefab ready to return, return that
    if (inactiveInstances.Count > 0) 
    {
        // remove the instance from teh collection of inactive instances
        spawnedGameObject = inactiveInstances.Pop();
    }
    // otherwise, create a new instance
    else 
    {
        spawnedGameObject = (GameObject)GameObject.Instantiate(prefab);

        // add the PooledObject component to the prefab so we know it came from this pool
        PooledObject pooledObject = spawnedGameObject.AddComponent<PooledObject>();
        pooledObject.pool = this;
    }

    // put the instance in the root of the scene and enable it
    spawnedGameObject.transform.SetParent(null);
    spawnedGameObject.SetActive(true);

    // return a reference to the instance
    return spawnedGameObject;
}

// Return an instance of the prefab to the pool
public void ReturnObject(GameObject toReturn) 
{
    PooledObject pooledObject = toReturn.GetComponent<PooledObject>();

    // if the instance came from this pool, return it to the pool
    if(pooledObject != null && pooledObject.pool == this)
    {
        // make the instance a child of this and disable it
        toReturn.transform.SetParent(transform);
        toReturn.SetActive(false);

        // add the instance to the collection of inactive instances
        inactiveInstances.Push(toReturn);
    }
    // otherwise, just destroy it
    else
    {
        Debug.LogWarning(toReturn.name + " was returned to a pool it wasn't spawned from! Destroying.");
        Destroy(toReturn);
    }
}
}

// a component that simply identifies the pool that a GameObject came from
public class PooledObject : MonoBehaviour
{
  public SimpleObjectPool pool;
}

It's untested, and vanilla 'psuedo' C# to give you a guideline

private List<int> _questions = null;
private int _current = 0;
void Start()
{
    _questions = Enumerable.Range(0, questionPool.Length).ToList();
    Shuffle(_questions);
}
void Shuffle(List<int> list)
{
    // put fisher-yates algorithm here to shuffle the numbers
}
void ShowQuestion()
{
    var idx = _questions[_current++];
    var questionData = questionPool[idx];
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM