You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity问答游戏实现6道不重复随机出题及评分功能求助

Fixing Random Non-Repeating Questions & Scoring for Your Quiz Game

Hey Rayllander, let's get your quiz game working properly with random, non-repeating questions and ensure you only show the final score after all 6 questions are answered. I'll walk you through the fixes step by step, keeping things clear since you mentioned your technical foundation is still growing.

Why Your Original Code Had Issues

  • Your current script uses sequential question IDs (idPergunta += 1), so there's no randomness at all.
  • When you tried Random.Range, you likely didn't track which questions were already used—this leads to duplicates or accidentally triggering the score screen early when you hit a repeated ID.
  • You couldn't use Shuffle or .Count because you're working with arrays (like string[] perguntas) instead of List<T>—arrays don't have built-in methods for shuffling or dynamic tracking of unused items.

Revised Script (With Full Explanations)

I've rewritten your script to use a List<int> to track unused question IDs. This way, we'll never repeat a question, and we'll only show the score once every question has been answered.

using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
using System.Collections.Generic; // Required for List<T> functionality

public class responder : MonoBehaviour 
{
    private int idTema;
    public Text pergunta;
    public Text respostaA;
    public Text respostaB;
    public Text respostaC;
    public Text respostaD;
    public Text InfoRespostas;

    public string[] perguntas;       // Stores all questions for the theme
    public string[] alternativaA;    // Stores all option A answers
    public string[] alternativaB;    // Stores all option B answers
    public string[] alternativaC;    // Stores all option C answers
    public string[] alternativaD;    // Stores all option D answers
    public string[] corretas;        // Stores all correct answers

    private float acertos;
    private float questoes;
    private float media;
    private int notaFinal;
    private int currentQuestionId;   // Tracks the ID of the currently displayed question
    private List<int> unusedQuestionIds; // Tracks which questions haven't been shown yet

    void Start () 
    {
        idTema = PlayerPrefs.GetInt ("idTema");
        questoes = perguntas.Length;

        // Validate that the theme has exactly 6 questions (as you requested)
        if(questoes != 6)
        {
            Debug.LogError("Warning: This theme doesn't have exactly 6 questions!");
        }

        // Fill the unused IDs list with all valid question indices
        unusedQuestionIds = new List<int>();
        for(int i = 0; i < perguntas.Length; i++)
        {
            unusedQuestionIds.Add(i);
        }

        // Show the first random question
        ShowRandomQuestion();
    }

    public void resposta (string alternativa) 
    {
        // Check if the selected answer matches the correct one for the current question
        if (alternativa == "A") 
        {
            if (alternativaA[currentQuestionId] == corretas[currentQuestionId])
                acertos += 1;
        } 
        else if (alternativa == "B") 
        {
            if (alternativaB[currentQuestionId] == corretas[currentQuestionId])
                acertos += 1;
        } 
        else if (alternativa == "C") 
        {
            if (alternativaC[currentQuestionId] == corretas[currentQuestionId])
                acertos += 1;
        } 
        else if (alternativa == "D") 
        {
            if (alternativaD[currentQuestionId] == corretas[currentQuestionId])
                acertos += 1;
        }

        // Move to the next question
        proximaPergunta();
    }

    void proximaPergunta() 
    {
        // Remove the current question from the unused list so it can't be reused
        unusedQuestionIds.Remove(currentQuestionId);

        // Check if there are any questions left to show
        if(unusedQuestionIds.Count > 0)
        {
            ShowRandomQuestion();
        }
        else
        {
            // All questions answered—calculate and save the final score
            media = 10 * (acertos / questoes);
            notaFinal = Mathf.RoundToInt(media);

            // Save the best score if the current score is higher
            if(notaFinal > PlayerPrefs.GetInt("notaFinal"+idTema.ToString()))
            {
                PlayerPrefs.SetInt ("notaFinal" + idTema.ToString (), notaFinal);
                PlayerPrefs.SetInt("acertos"+idTema.ToString(), (int) acertos);
            }

            // Save temporary score data for the results screen
            PlayerPrefs.SetInt ("notaFinalTemp" + idTema.ToString (), notaFinal);
            PlayerPrefs.SetInt("acertosTemp"+idTema.ToString(), (int) acertos);

            SceneManager.LoadScene ("notaFinal");
        }
    }

    void ShowRandomQuestion()
    {
        // Pick a random index from the list of unused questions
        int randomIndex = Random.Range(0, unusedQuestionIds.Count);
        currentQuestionId = unusedQuestionIds[randomIndex];

        // Update the UI with the selected question and options
        pergunta.text = perguntas[currentQuestionId];
        respostaA.text = alternativaA[currentQuestionId];
        respostaB.text = alternativaB[currentQuestionId];
        respostaC.text = alternativaC[currentQuestionId];
        respostaD.text = alternativaD[currentQuestionId];

        // Update the progress text to show how many questions have been answered
        int questionsAnswered = (int)questoes - unusedQuestionIds.Count;
        InfoRespostas.text = $"Respondendo {questionsAnswered + 1} de {questoes} perguntas.";
    }

    // Optional: If you prefer to shuffle all questions upfront instead of picking random each time
    void ShuffleList<T>(List<T> list)
    {
        int n = list.Count;
        while (n > 1)
        {
            n--;
            int k = Random.Range(0, n + 1);
            T temp = list[k];
            list[k] = list[n];
            list[n] = temp;
        }
    }
}

Key Changes Explained

  1. List<int> unusedQuestionIds: This list keeps track of all question IDs that haven't been shown yet. We fill it in Start() with every valid question index for the theme.
  2. currentQuestionId: This variable tracks which question is currently displayed, so we can correctly check if the player's answer is right.
  3. ShowRandomQuestion(): This method picks a random unused question ID, updates the UI with that question's content, and shows the player's progress.
  4. Fixed end condition: Instead of using a sequential counter, we check if the unused IDs list is empty—this guarantees we only jump to the score screen after all 6 questions are answered.
  5. Theme validation: The script logs an error if a theme doesn't have exactly 6 questions, helping you catch setup mistakes quickly.

How to Use This Script

  • Ensure all your arrays (perguntas, alternativaA, etc.) have exactly 6 elements per theme.
  • Attach this script to your quiz UI manager object as you did before.
  • Link all your UI Text elements to the public fields in the Inspector.

That's it! Now your game will show 6 random, non-repeating questions every time, and only move to the score screen once all questions are completed.

内容的提问来源于stack exchange,提问作者Rayllander

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 10:17:04