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
Shuffleor.Countbecause you're working with arrays (likestring[] perguntas) instead ofList<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
List<int> unusedQuestionIds: This list keeps track of all question IDs that haven't been shown yet. We fill it inStart()with every valid question index for the theme.currentQuestionId: This variable tracks which question is currently displayed, so we can correctly check if the player's answer is right.ShowRandomQuestion(): This method picks a random unused question ID, updates the UI with that question's content, and shows the player's progress.- 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.
- 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
相关产品推荐
相关产品推荐

