Files
Benjamin Boenisch 5a31f52310 Initial commit: breakpilot-lehrer - Lehrer KI Platform
Services: Admin-Lehrer, Backend-Lehrer, Studio v2, Website,
Klausur-Service, School-Service, Voice-Service, Geo-Service,
BreakPilot Drive, Agent-Core

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 23:47:26 +01:00

341 lines
11 KiB
C#

// ==============================================
// 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<TextMeshProUGUI>();
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<Image>().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<TextMeshProUGUI>();
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;
}
}
}