// ============================================== // QuizOverlay.cs - Quiz-UI Anzeige // ============================================== // Zeigt Quiz-Fragen an (Quick und Pause Mode) // mit Timer, Antwort-Buttons und Feedback. using System.Collections; using UnityEngine; using UnityEngine.UI; using TMPro; namespace BreakpilotDrive { public class QuizOverlay : MonoBehaviour { [Header("Panels")] [SerializeField] private GameObject quickQuizPanel; [SerializeField] private GameObject pauseQuizPanel; [SerializeField] private GameObject feedbackPanel; [Header("Quick Quiz UI")] [SerializeField] private TextMeshProUGUI quickQuestionText; [SerializeField] private Button[] quickAnswerButtons; [SerializeField] private Slider timerSlider; [SerializeField] private TextMeshProUGUI timerText; [Header("Pause Quiz UI")] [SerializeField] private TextMeshProUGUI pauseQuestionText; [SerializeField] private Button[] pauseAnswerButtons; [SerializeField] private TextMeshProUGUI pauseHintText; [Header("Feedback UI")] [SerializeField] private TextMeshProUGUI feedbackText; [SerializeField] private Image feedbackIcon; [SerializeField] private Sprite correctIcon; [SerializeField] private Sprite wrongIcon; [Header("Farben")] [SerializeField] private Color normalColor = Color.white; [SerializeField] private Color correctColor = Color.green; [SerializeField] private Color wrongColor = Color.red; [SerializeField] private Color selectedColor = Color.yellow; [Header("Animation")] [SerializeField] private Animator quizAnimator; [SerializeField] private float feedbackDuration = 1.5f; // Aktuelle Frage private QuizQuestion currentQuestion; private int selectedAnswer = -1; private bool isAnswered = false; void Start() { // Panels verstecken HideAll(); // QuizManager Events abonnieren if (QuizManager.Instance != null) { QuizManager.Instance.OnQuizStarted += OnQuizStarted; QuizManager.Instance.OnQuizEnded += OnQuizEnded; QuizManager.Instance.OnQuestionAnswered += OnQuestionAnswered; } // Button-Listener einrichten SetupButtons(); } void OnDestroy() { if (QuizManager.Instance != null) { QuizManager.Instance.OnQuizStarted -= OnQuizStarted; QuizManager.Instance.OnQuizEnded -= OnQuizEnded; QuizManager.Instance.OnQuestionAnswered -= OnQuestionAnswered; } } // ============================================== // Button Setup // ============================================== private void SetupButtons() { // Quick Answer Buttons for (int i = 0; i < quickAnswerButtons.Length; i++) { int index = i; quickAnswerButtons[i].onClick.AddListener(() => OnAnswerClicked(index)); } // Pause Answer Buttons for (int i = 0; i < pauseAnswerButtons.Length; i++) { int index = i; pauseAnswerButtons[i].onClick.AddListener(() => OnAnswerClicked(index)); } } // ============================================== // Quiz Events // ============================================== private void OnQuizStarted() { isAnswered = false; selectedAnswer = -1; } private void OnQuizEnded() { StartCoroutine(HideAfterDelay(feedbackDuration)); } private void OnQuestionAnswered(bool correct, int points) { isAnswered = true; ShowFeedback(correct, points); } // ============================================== // Quick Quiz anzeigen // ============================================== public void ShowQuickQuiz(QuizQuestion question, float timeLimit) { currentQuestion = question; isAnswered = false; // Panel aktivieren HideAll(); if (quickQuizPanel) quickQuizPanel.SetActive(true); // Frage anzeigen if (quickQuestionText) quickQuestionText.text = question.question_text; // Antworten anzeigen for (int i = 0; i < quickAnswerButtons.Length; i++) { if (i < question.options.Length) { quickAnswerButtons[i].gameObject.SetActive(true); var text = quickAnswerButtons[i].GetComponentInChildren(); if (text) text.text = $"[{i + 1}] {question.options[i]}"; ResetButtonColor(quickAnswerButtons[i]); } else { quickAnswerButtons[i].gameObject.SetActive(false); } } // Timer starten StartCoroutine(UpdateTimer(timeLimit)); // Animation if (quizAnimator) quizAnimator.SetTrigger("ShowQuick"); } private IEnumerator UpdateTimer(float duration) { float timeRemaining = duration; while (timeRemaining > 0 && !isAnswered) { timeRemaining -= Time.deltaTime; // UI aktualisieren if (timerSlider) timerSlider.value = timeRemaining / duration; if (timerText) timerText.text = $"{timeRemaining:F1}s"; // Farbe aendern wenn Zeit knapp if (timerSlider && timeRemaining < duration * 0.3f) { timerSlider.fillRect.GetComponent().color = Color.red; } yield return null; } } // ============================================== // Pause Quiz anzeigen // ============================================== public void ShowPauseQuiz(QuizQuestion question) { currentQuestion = question; isAnswered = false; // Panel aktivieren HideAll(); if (pauseQuizPanel) pauseQuizPanel.SetActive(true); // Frage anzeigen if (pauseQuestionText) pauseQuestionText.text = question.question_text; // Hint anzeigen (falls aktiviert) if (pauseHintText) { bool hintsEnabled = GameManager.Instance?.DifficultySettings?.hints_enabled ?? false; pauseHintText.gameObject.SetActive(hintsEnabled); // TODO: Hint-Text generieren } // Antworten anzeigen for (int i = 0; i < pauseAnswerButtons.Length; i++) { if (i < question.options.Length) { pauseAnswerButtons[i].gameObject.SetActive(true); var text = pauseAnswerButtons[i].GetComponentInChildren(); if (text) text.text = $"[{i + 1}] {question.options[i]}"; ResetButtonColor(pauseAnswerButtons[i]); } else { pauseAnswerButtons[i].gameObject.SetActive(false); } } // Animation if (quizAnimator) quizAnimator.SetTrigger("ShowPause"); } // ============================================== // Antwort-Handling // ============================================== private void OnAnswerClicked(int index) { if (isAnswered || currentQuestion == null) return; selectedAnswer = index; // Button hervorheben Button[] buttons = currentQuestion.quiz_mode == "quick" ? quickAnswerButtons : pauseAnswerButtons; if (index < buttons.Length) { HighlightButton(buttons[index]); } // An QuizManager melden (wird dort verarbeitet) // QuizManager ruft dann OnQuestionAnswered auf } // ============================================== // Feedback anzeigen // ============================================== private void ShowFeedback(bool correct, int points) { // Richtige Antwort markieren Button[] buttons = currentQuestion?.quiz_mode == "quick" ? quickAnswerButtons : pauseAnswerButtons; if (currentQuestion != null && buttons != null) { int correctIndex = currentQuestion.correct_index; if (correctIndex >= 0 && correctIndex < buttons.Length) { SetButtonColor(buttons[correctIndex], correctColor); } // Falsche Antwort rot markieren if (!correct && selectedAnswer >= 0 && selectedAnswer < buttons.Length) { SetButtonColor(buttons[selectedAnswer], wrongColor); } } // Feedback Panel if (feedbackPanel) { feedbackPanel.SetActive(true); if (feedbackText) { string pointsStr = points >= 0 ? $"+{points}" : $"{points}"; feedbackText.text = correct ? $"Richtig! {pointsStr} Punkte" : $"Leider falsch. {pointsStr} Punkte"; feedbackText.color = correct ? correctColor : wrongColor; } if (feedbackIcon) { feedbackIcon.sprite = correct ? correctIcon : wrongIcon; } } // Sound abspielen if (correct) { AudioManager.Instance?.PlayCorrectSound(); } else { AudioManager.Instance?.PlayWrongSound(); } // Animation if (quizAnimator) { quizAnimator.SetTrigger(correct ? "Correct" : "Wrong"); } } // ============================================== // Helper // ============================================== private void HideAll() { if (quickQuizPanel) quickQuizPanel.SetActive(false); if (pauseQuizPanel) pauseQuizPanel.SetActive(false); if (feedbackPanel) feedbackPanel.SetActive(false); } private IEnumerator HideAfterDelay(float delay) { yield return new WaitForSecondsRealtime(delay); HideAll(); } private void ResetButtonColor(Button button) { SetButtonColor(button, normalColor); } private void HighlightButton(Button button) { SetButtonColor(button, selectedColor); } private void SetButtonColor(Button button, Color color) { var colors = button.colors; colors.normalColor = color; colors.highlightedColor = color; button.colors = colors; } } }