
QuizCanvas에 ScoreKeeper 만들기
ScoreKeeper.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ScoreKeeper : MonoBehaviour
{
int correctAnswers = 0;
int questionsSeen = 0;
public int GetCorrectAnswers()
{
return correctAnswers;
}
public void IncrementCorrectAnswers()
{
correctAnswers++;
}
public int GetQuestionSeen()
{
return questionsSeen;
}
public void IncrementQuestionsSeen()
{
questionsSeen++;
}
public int CalculateScore()
{
return Mathf.RoundToInt(correctAnswers / (float)questionsSeen * 100);
}
}
Quiz.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;
using UnityEngine.UI;
public class Quiz : MonoBehaviour
{
[Header("Questions")]
[SerializeField] TextMeshProUGUI questionText;
[SerializeField] List<QuestionSO> questions = new List<QuestionSO>();
QuestionSO currentQuestion;
[Header("Answers")]
[SerializeField] GameObject[] answerButtons;
int correctAnswerIndex;
bool hasAnsweredEarly;
[Header("Button Colors")]
[SerializeField] Sprite defaultAnswerSprite;
[SerializeField] Sprite correctAnswerSprite;
[Header("Timer")]
[SerializeField] Image timerImage;
Timer timer;
[Header("Scoring")]
[SerializeField] TextMeshProUGUI scoreText;
ScoreKeeper scoreKeeper;
void Start()
{
timer = FindObjectOfType<Timer>();
scoreKeeper = FindObjectOfType<ScoreKeeper>();
}
void Update()
{
timerImage.fillAmount = timer.fillFraction;
if(timer.loadNextQuestion)
{
hasAnsweredEarly = false;
GetNextQuestion();
timer.loadNextQuestion = false;
}
else if(!hasAnsweredEarly && !timer.isAnsweringQuestion)
{
DisplayAnswer(-1);
SetButtonState(false);
}
}
public void OnAnswerSelected(int index)
{
hasAnsweredEarly = true;
DisplayAnswer(index);
SetButtonState(false);
timer.CancelTimer();
scoreText.text = "Score: " + scoreKeeper.CalculateScore() + "%";
}
void DisplayAnswer(int index)
{
Image buttonImage;
if(index == currentQuestion.GetCorrectAnswerIndex())
{
questionText.text = "Correct!";
buttonImage = answerButtons[index].GetComponent<Image>();
buttonImage.sprite = correctAnswerSprite;
scoreKeeper.IncrementCorrectAnswers();
}
else
{
correctAnswerIndex = currentQuestion.GetCorrectAnswerIndex();
string correctAnswer = currentQuestion.GetAnswer(correctAnswerIndex);
questionText.text = "Sorry, the correct answer was;\n" + correctAnswer;
buttonImage = answerButtons[correctAnswerIndex].GetComponent<Image>();
buttonImage.sprite = correctAnswerSprite;
}
}
void GetNextQuestion()
{
if(questions.Count > 0)
{
SetButtonState(true);
SetDefaultButtonSprites();
GetRandomQuestion();
DisplayQuestion();
scoreKeeper.IncrementCorrectAnswers();
}
}
void GetRandomQuestion()
{
int index = Random.Range(0, questions.Count);
currentQuestion = questions[index];
if(questions.Contains(currentQuestion))
{
questions.Remove(currentQuestion);
}
}
void DisplayQuestion()
{
questionText.text = currentQuestion.GetQuestion();
for (int i = 0; i < answerButtons.Length; i++)
{
TextMeshProUGUI buttonText = answerButtons[i].GetComponentInChildren<TextMeshProUGUI>();
buttonText.text = currentQuestion.GetAnswer(i);
}
}
void SetButtonState(bool state)
{
for(int i = 0; i < answerButtons.Length; i++)
{
Button button = answerButtons[i].GetComponent<Button>();
button.interactable = state;
}
}
void SetDefaultButtonSprites()
{
for(int i = 0; i < answerButtons.Length; i++)
{
Image buttonImage = answerButtons[i].GetComponent<Image>();
buttonImage.sprite = defaultAnswerSprite;
}
}
}
QuizCanvas에 Slider 추가
Quiz.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;
using UnityEngine.UI;
public class Quiz : MonoBehaviour
{
[Header("Questions")]
[SerializeField] TextMeshProUGUI questionText;
[SerializeField] List<QuestionSO> questions = new List<QuestionSO>();
QuestionSO currentQuestion;
[Header("Answers")]
[SerializeField] GameObject[] answerButtons;
int correctAnswerIndex;
bool hasAnsweredEarly;
[Header("Button Colors")]
[SerializeField] Sprite defaultAnswerSprite;
[SerializeField] Sprite correctAnswerSprite;
[Header("Timer")]
[SerializeField] Image timerImage;
Timer timer;
[Header("Scoring")]
[SerializeField] TextMeshProUGUI scoreText;
ScoreKeeper scoreKeeper;
[Header("ProgressBar")]
[SerializeField] Slider progressBar;
public bool isComplete;
void Start()
{
timer = FindObjectOfType<Timer>();
scoreKeeper = FindObjectOfType<ScoreKeeper>();
progressBar.maxValue = questions.Count;
progressBar.value = 0;
}
void Update()
{
timerImage.fillAmount = timer.fillFraction;
if(timer.loadNextQuestion)
{
hasAnsweredEarly = false;
GetNextQuestion();
timer.loadNextQuestion = false;
}
else if(!hasAnsweredEarly && !timer.isAnsweringQuestion)
{
DisplayAnswer(-1);
SetButtonState(false);
}
}
public void OnAnswerSelected(int index)
{
hasAnsweredEarly = true;
DisplayAnswer(index);
SetButtonState(false);
timer.CancelTimer();
scoreText.text = "Score: " + scoreKeeper.CalculateScore() + "%";
if(progressBar.value == progressBar.maxValue)
{
isComplete = true;
}
}
void DisplayAnswer(int index)
{
Image buttonImage;
if(index == currentQuestion.GetCorrectAnswerIndex())
{
questionText.text = "Correct!";
buttonImage = answerButtons[index].GetComponent<Image>();
buttonImage.sprite = correctAnswerSprite;
scoreKeeper.IncrementCorrectAnswers();
}
else
{
correctAnswerIndex = currentQuestion.GetCorrectAnswerIndex();
string correctAnswer = currentQuestion.GetAnswer(correctAnswerIndex);
questionText.text = "Sorry, the correct answer was;\n" + correctAnswer;
buttonImage = answerButtons[correctAnswerIndex].GetComponent<Image>();
buttonImage.sprite = correctAnswerSprite;
}
}
void GetNextQuestion()
{
if(questions.Count > 0)
{
SetButtonState(true);
SetDefaultButtonSprites();
GetRandomQuestion();
DisplayQuestion();
progressBar.value++;
scoreKeeper.IncrementCorrectAnswers();
}
}
void GetRandomQuestion()
{
int index = Random.Range(0, questions.Count);
currentQuestion = questions[index];
if(questions.Contains(currentQuestion))
{
questions.Remove(currentQuestion);
}
}
void DisplayQuestion()
{
questionText.text = currentQuestion.GetQuestion();
for (int i = 0; i < answerButtons.Length; i++)
{
TextMeshProUGUI buttonText = answerButtons[i].GetComponentInChildren<TextMeshProUGUI>();
buttonText.text = currentQuestion.GetAnswer(i);
}
}
void SetButtonState(bool state)
{
for(int i = 0; i < answerButtons.Length; i++)
{
Button button = answerButtons[i].GetComponent<Button>();
button.interactable = state;
}
}
void SetDefaultButtonSprites()
{
for(int i = 0; i < answerButtons.Length; i++)
{
Image buttonImage = answerButtons[i].GetComponent<Image>();
buttonImage.sprite = defaultAnswerSprite;
}
}
}
Slider 버그 수정
-> Interactable 토글 끄기
WinCanvas 추가 - Sort Order 2로 바꾸기
WinCanvas에 Text-TMP, Button-TMP 추가
EndScreen.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;
public class EndScreen : MonoBehaviour
{
[SerializeField] TextMeshProUGUI finalScoreText;
ScoreKeeper scoreKeeper;
void Start()
{
scoreKeeper = FindObjectOfType<ScoreKeeper>();
}
public void ShowFinalScore()
{
finalScoreText.text = "Congratulations!\nYou got a score of " + scoreKeeper.CalculateScore() + "%";
}
}
Create Empty - GameManager 추가
GameManager.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class GameManager : MonoBehaviour
{
Quiz quiz;
EndScreen endScreen;
void Awake()
{
quiz = FindObjectOfType<Quiz>();
endScreen = FindObjectOfType<EndScreen>();
}
void Start()
{
quiz.gameObject.SetActive(true);
endScreen.gameObject.SetActive(false);
}
void Update()
{
if(quiz.isComplete)
{
quiz.gameObject.SetActive(false);
endScreen.gameObject.SetActive(true);
endScreen.ShowFinalScore();
}
}
public void OnReplayLevel()
{
SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex);
}
}
ScoreKeeper.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ScoreKeeper : MonoBehaviour
{
int correctAnswers = 0;
int questionsSeen = 0;
public int GetCorrectAnswers()
{
return correctAnswers;
}
public void IncrementCorrectAnswers()
{
correctAnswers++;
}
public int GetQuestionSeen()
{
return questionsSeen;
}
public void IncrementQuestionsSeen()
{
questionsSeen++;
}
public int CalculateScore()
{
return Mathf.RoundToInt(correctAnswers / (float)questionsSeen * 100);
}
}
Quiz.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;
using UnityEngine.UI;
public class Quiz : MonoBehaviour
{
[Header("Questions")]
[SerializeField] TextMeshProUGUI questionText;
[SerializeField] List<QuestionSO> questions = new List<QuestionSO>();
QuestionSO currentQuestion;
[Header("Answers")]
[SerializeField] GameObject[] answerButtons;
int correctAnswerIndex;
bool hasAnsweredEarly = true;
[Header("Button Colors")]
[SerializeField] Sprite defaultAnswerSprite;
[SerializeField] Sprite correctAnswerSprite;
[Header("Timer")]
[SerializeField] Image timerImage;
Timer timer;
[Header("Scoring")]
[SerializeField] TextMeshProUGUI scoreText;
ScoreKeeper scoreKeeper;
[Header("ProgressBar")]
[SerializeField] Slider progressBar;
public bool isComplete;
void Awake()
{
timer = FindObjectOfType<Timer>();
scoreKeeper = FindObjectOfType<ScoreKeeper>();
progressBar.maxValue = questions.Count;
progressBar.value = 0;
}
void Update()
{
timerImage.fillAmount = timer.fillFraction;
if(timer.loadNextQuestion)
{
if (progressBar.value == progressBar.maxValue)
{
isComplete = true;
return;
}
hasAnsweredEarly = false;
GetNextQuestion();
timer.loadNextQuestion = false;
}
else if(!hasAnsweredEarly && !timer.isAnsweringQuestion)
{
DisplayAnswer(-1);
SetButtonState(false);
}
}
public void OnAnswerSelected(int index)
{
hasAnsweredEarly = true;
DisplayAnswer(index);
SetButtonState(false);
timer.CancelTimer();
scoreText.text = "Score: " + scoreKeeper.CalculateScore() + "%";
}
void DisplayAnswer(int index)
{
Image buttonImage;
if(index == currentQuestion.GetCorrectAnswerIndex())
{
questionText.text = "Correct!";
buttonImage = answerButtons[index].GetComponent<Image>();
buttonImage.sprite = correctAnswerSprite;
scoreKeeper.IncrementCorrectAnswers();
}
else
{
correctAnswerIndex = currentQuestion.GetCorrectAnswerIndex();
string correctAnswer = currentQuestion.GetAnswer(correctAnswerIndex);
questionText.text = "Sorry, the correct answer was;\n" + correctAnswer;
buttonImage = answerButtons[correctAnswerIndex].GetComponent<Image>();
buttonImage.sprite = correctAnswerSprite;
}
}
void GetNextQuestion()
{
if(questions.Count > 0)
{
SetButtonState(true);
SetDefaultButtonSprites();
GetRandomQuestion();
DisplayQuestion();
progressBar.value++;
scoreKeeper.IncrementCorrectAnswers();
}
}
void GetRandomQuestion()
{
int index = Random.Range(0, questions.Count);
currentQuestion = questions[index];
if(questions.Contains(currentQuestion))
{
questions.Remove(currentQuestion);
}
}
void DisplayQuestion()
{
questionText.text = currentQuestion.GetQuestion();
for (int i = 0; i < answerButtons.Length; i++)
{
TextMeshProUGUI buttonText = answerButtons[i].GetComponentInChildren<TextMeshProUGUI>();
buttonText.text = currentQuestion.GetAnswer(i);
}
}
void SetButtonState(bool state)
{
for(int i = 0; i < answerButtons.Length; i++)
{
Button button = answerButtons[i].GetComponent<Button>();
button.interactable = state;
}
}
void SetDefaultButtonSprites()
{
for(int i = 0; i < answerButtons.Length; i++)
{
Image buttonImage = answerButtons[i].GetComponent<Image>();
buttonImage.sprite = defaultAnswerSprite;
}
}
}
EndScreen.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;
public class EndScreen : MonoBehaviour
{
[SerializeField] TextMeshProUGUI finalScoreText;
ScoreKeeper scoreKeeper;
void Awake()
{
scoreKeeper = FindObjectOfType<ScoreKeeper>();
}
public void ShowFinalScore()
{
finalScoreText.text = "Congratulations!\nYou got a score of " +
scoreKeeper.CalculateScore() + "%";
}
}
ReplayButton의 On Click() 에 GameManager 추가한 뒤 Function에 GameManager.OnReplayLevel 설정

끝~!