
QuizCanvas > UI > Image
TimeImage(타이머) 생성하기

Image Type 설정

Timer C# 스크립트 생성, Empty 객체 만들고 Timer 로 명명
Timer Script 가 해야할 일
- 게임이 어떤 상태에 있는가?
- 플레이어가 정답을 보고 있는지 문제를 풀고 있는지
- 해당 상태에서 시간이 다 되었는가?
- 시간이 남아있다면: 타이머 이미지에 사용할 Fill Amount 정보 관리
- 시간이 다 되면: 게임 상태 변경
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Timer : MonoBehaviour
{
[SerializeField] float timeToCompleteQuestion = 30f;
[SerializeField] float timeToShowCorrectAnswer = 10f;
public bool isAnsweringQuestion = false;
float timerValue;
void Update()
{
UpdateTimer();
}
void UpdateTimer()
{
timerValue -= Time.deltaTime;
if(isAnsweringQuestion)
{
if(timerValue <= 0)
{
isAnsweringQuestion = false;
timerValue = timeToShowCorrectAnswer;
}
}
else
{
if(timerValue <= 0)
{
isAnsweringQuestion = true;
timerValue = timeToCompleteQuestion;
}
}
Debug.Log(timerValue);
}
}

Timer Image를 타이머가 부여한 시간에 따라 0~1까지로 표준화 하여 분수로 반환
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Timer : MonoBehaviour
{
[SerializeField] float timeToCompleteQuestion = 30f;
[SerializeField] float timeToShowCorrectAnswer = 10f;
public bool loadNextQuestion;
public bool isAnsweringQuestion = false;
public float fillFraction;
float timerValue;
void Update()
{
UpdateTimer();
}
public void CancelTomer()
{
timerValue = 0;
}
void UpdateTimer()
{
timerValue -= Time.deltaTime;
if(isAnsweringQuestion)
{
if(timerValue > 0)
{
fillFraction = timerValue / timeToCompleteQuestion;
}
else
{
isAnsweringQuestion = false;
timerValue = timeToShowCorrectAnswer;
}
}
else
{
if(timerValue > 0)
{
fillFraction = timerValue / timeToShowCorrectAnswer;
}
else
{
isAnsweringQuestion = true;
timerValue = timeToCompleteQuestion;
loadNextQuestion = true;
}
}
Debug.Log(isAnsweringQuestion + ": " + timerValue + " = " + fillFraction);
}
}
Timer Script와 Quiz Script 연결하기
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Timer : MonoBehaviour
{
[SerializeField] float timeToCompleteQuestion = 30f;
[SerializeField] float timeToShowCorrectAnswer = 10f;
public bool loadNextQuestion;
public bool isAnsweringQuestion;
public float fillFraction;
float timerValue;
void Update()
{
UpdateTimer();
}
public void CancelTimer()
{
timerValue = 0;
}
void UpdateTimer()
{
timerValue -= Time.deltaTime;
if(isAnsweringQuestion)
{
if(timerValue > 0)
{
fillFraction = timerValue / timeToCompleteQuestion;
}
else
{
isAnsweringQuestion = false;
timerValue = timeToShowCorrectAnswer;
}
}
else
{
if(timerValue > 0)
{
fillFraction = timerValue / timeToShowCorrectAnswer;
}
else
{
isAnsweringQuestion = true;
timerValue = timeToCompleteQuestion;
loadNextQuestion = true;
}
}
Debug.Log(isAnsweringQuestion + ": " + timerValue + " = " + fillFraction);
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;
using UnityEngine.UI;
public class Quiz : MonoBehaviour
{
[Header("Questions")]
[SerializeField] TextMeshProUGUI questionText;
[SerializeField] QuestionSO question;
[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;
void Start()
{
timer = FindObjectOfType<Timer>();
GetNextQuestion();
//DisplayQuesetion();
}
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();
}
void DisplayAnswer(int index)
{
Image buttonImage;
if(index == question.GetCorrectAnswerIndex())
{
questionText.text = "Correct!";
buttonImage = answerButtons[index].GetComponent<Image>();
buttonImage.sprite = correctAnswerSprite;
}
else
{
correctAnswerIndex = question.GetCorrectAnswerIndex();
string correctAnswer = question.GetAnswer(correctAnswerIndex);
questionText.text = "Sorry, the correct answer was;\n" + correctAnswer;
buttonImage = answerButtons[correctAnswerIndex].GetComponent<Image>();
buttonImage.sprite = correctAnswerSprite;
}
}
void GetNextQuestion()
{
SetButtonState(true);
SetDefaultButtonSprites();
DisplayQuestion();
}
void DisplayQuestion()
{
questionText.text = question.GetQuestion();
for (int i = 0; i < answerButtons.Length; i++)
{
TextMeshProUGUI buttonText = answerButtons[i].GetComponentInChildren<TextMeshProUGUI>();
buttonText.text = question.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;
}
}
}

퀴즈 리스트 만들기
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;
void Start()
{
timer = FindObjectOfType<Timer>();
}
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();
}
void DisplayAnswer(int index)
{
Image buttonImage;
if(index == currentQuestion.GetCorrectAnswerIndex())
{
questionText.text = "Correct!";
buttonImage = answerButtons[index].GetComponent<Image>();
buttonImage.sprite = correctAnswerSprite;
}
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();
}
}
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;
}
}
}
