1223 lines
32 KiB
C#
1223 lines
32 KiB
C#
|
|
using UnityEngine;
|
|||
|
|
using UnityEngine.UI;
|
|||
|
|
using TMPro;
|
|||
|
|
using UnityEngine.SceneManagement;
|
|||
|
|
using System.Collections;
|
|||
|
|
using System.Collections.Generic;
|
|||
|
|
|
|||
|
|
public class DialogueComplete22Mod : MonoBehaviour
|
|||
|
|
{
|
|||
|
|
[Header("DATA")]
|
|||
|
|
public TextAsset wordFile;
|
|||
|
|
public string wordsResourcePath = "Mod22Words";
|
|||
|
|
|
|||
|
|
[Header("MAIN DIALOGUE TEXT")]
|
|||
|
|
[Tooltip("Ekranda kısa diyalog burada gösterilecek.")]
|
|||
|
|
public TMP_Text dialogueText;
|
|||
|
|
|
|||
|
|
[Header("TEXTS")]
|
|||
|
|
public TMP_Text titleText;
|
|||
|
|
public TMP_Text languageText;
|
|||
|
|
public TMP_Text feedbackText;
|
|||
|
|
public TMP_Text scoreText;
|
|||
|
|
public TMP_Text comboText;
|
|||
|
|
public TMP_Text timerText;
|
|||
|
|
|
|||
|
|
[Header("OPTIONAL TEXTS")]
|
|||
|
|
public TMP_Text questionCounterText;
|
|||
|
|
public TMP_Text accuracyText;
|
|||
|
|
public TMP_Text streakText;
|
|||
|
|
|
|||
|
|
[Header("ANSWER BUTTONS")]
|
|||
|
|
public Button[] answerButtons;
|
|||
|
|
public TMP_Text[] answerTexts;
|
|||
|
|
|
|||
|
|
[Header("MAIN BUTTONS")]
|
|||
|
|
public Button submitButton;
|
|||
|
|
public Button backButton;
|
|||
|
|
|
|||
|
|
[Header("EXTRA BUTTONS")]
|
|||
|
|
public Button extraTimeButton;
|
|||
|
|
public Button extraHintButton;
|
|||
|
|
public Button extraSkipButton;
|
|||
|
|
public TMP_Text extraTimeCooldownText;
|
|||
|
|
public TMP_Text extraHintCooldownText;
|
|||
|
|
public TMP_Text extraSkipCooldownText;
|
|||
|
|
|
|||
|
|
[Header("SCENES")]
|
|||
|
|
public string backSceneName = "modsec 22";
|
|||
|
|
public string resultSceneName = "modres 22";
|
|||
|
|
|
|||
|
|
[Header("LANGUAGE TEST")]
|
|||
|
|
[Tooltip("-1 otomatik. 0 TR, 1 EN, 2 ES, 3 DE, 4 FR, 5 PT | QuestionLangID = ekrandaki diyalog dili")]
|
|||
|
|
public int forcedQuestionLanguageIndex = -1;
|
|||
|
|
|
|||
|
|
[Tooltip("-1 otomatik. 0 TR, 1 EN, 2 ES, 3 DE, 4 FR, 5 PT | AnswerLangID = şıklardaki cevap dili")]
|
|||
|
|
public int forcedAnswerLanguageIndex = -1;
|
|||
|
|
|
|||
|
|
[Header("GAME SETTINGS")]
|
|||
|
|
public float startTime = 60f;
|
|||
|
|
public bool useSelectedGameTime = true;
|
|||
|
|
public int basePoints = 50;
|
|||
|
|
public int wrongPenalty = 50;
|
|||
|
|
public float correctTimeBonus = 2f;
|
|||
|
|
public float wrongTimePenalty = 0f;
|
|||
|
|
public float nextQuestionDelay = 1.05f;
|
|||
|
|
|
|||
|
|
[Header("EXTRA SETTINGS")]
|
|||
|
|
public float extraTimeAmount = 5f;
|
|||
|
|
public float cooldownDuration = 5f;
|
|||
|
|
|
|||
|
|
[Header("COMBO MULTIPLIERS")]
|
|||
|
|
public float mult_1to2 = 1f;
|
|||
|
|
public float mult_3to4 = 1.15f;
|
|||
|
|
public float mult_5to7 = 1.3f;
|
|||
|
|
public float mult_8plus = 1.5f;
|
|||
|
|
|
|||
|
|
[Header("COLORS")]
|
|||
|
|
public Color normalButtonColor = new Color32(120, 70, 220, 245);
|
|||
|
|
public Color selectedButtonColor = new Color32(165, 115, 255, 255);
|
|||
|
|
public Color correctButtonColor = new Color32(70, 240, 130, 255);
|
|||
|
|
public Color wrongButtonColor = new Color32(255, 80, 95, 255);
|
|||
|
|
public Color disabledButtonColor = new Color32(90, 75, 120, 170);
|
|||
|
|
|
|||
|
|
readonly string[] langNames = { "Türkçe", "English", "Español", "Deutsch", "Français", "Português" };
|
|||
|
|
|
|||
|
|
const string modKey = "Mod22";
|
|||
|
|
|
|||
|
|
class DialogueEntry
|
|||
|
|
{
|
|||
|
|
public string[] dialogues = new string[6];
|
|||
|
|
|
|||
|
|
// Her dil için 4 cevap şıkkı:
|
|||
|
|
// 0 doğru
|
|||
|
|
// 1 yanlış
|
|||
|
|
// 2 yanlış
|
|||
|
|
// 3 yanlış
|
|||
|
|
public string[] options = new string[24];
|
|||
|
|
|
|||
|
|
public int sourceLine;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
readonly List<DialogueEntry> allQuestions = new List<DialogueEntry>();
|
|||
|
|
readonly List<DialogueEntry> questionPool = new List<DialogueEntry>();
|
|||
|
|
|
|||
|
|
DialogueEntry currentQuestion;
|
|||
|
|
|
|||
|
|
int screenLangIndex = 1;
|
|||
|
|
int optionLangIndex = 0;
|
|||
|
|
|
|||
|
|
int selectedAnswer = -1;
|
|||
|
|
int correctAnswerIndex = -1;
|
|||
|
|
int questionNumber = 0;
|
|||
|
|
|
|||
|
|
int score = 0;
|
|||
|
|
int combo = 0;
|
|||
|
|
int correctCount = 0;
|
|||
|
|
int wrongCount = 0;
|
|||
|
|
int bestComboThisRun = 0;
|
|||
|
|
|
|||
|
|
float timeLeft;
|
|||
|
|
|
|||
|
|
bool gameOver = false;
|
|||
|
|
bool waitingNextQuestion = false;
|
|||
|
|
|
|||
|
|
bool extraTimeReady = true;
|
|||
|
|
bool extraHintReady = true;
|
|||
|
|
bool extraSkipReady = true;
|
|||
|
|
|
|||
|
|
Vector3[] originalButtonScales;
|
|||
|
|
Vector3[] originalButtonPositions;
|
|||
|
|
|
|||
|
|
void Awake()
|
|||
|
|
{
|
|||
|
|
LoadQuestions();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void Start()
|
|||
|
|
{
|
|||
|
|
ResolveLanguages();
|
|||
|
|
|
|||
|
|
timeLeft = startTime;
|
|||
|
|
|
|||
|
|
if (useSelectedGameTime)
|
|||
|
|
{
|
|||
|
|
float selectedTime = PlayerPrefs.GetFloat("SelectedGameTime", startTime);
|
|||
|
|
|
|||
|
|
if (selectedTime > 0f)
|
|||
|
|
timeLeft = selectedTime;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (timeLeft <= 0f)
|
|||
|
|
timeLeft = 60f;
|
|||
|
|
|
|||
|
|
if (!ValidateRequiredReferences())
|
|||
|
|
return;
|
|||
|
|
|
|||
|
|
if (allQuestions.Count < 1)
|
|||
|
|
{
|
|||
|
|
Debug.LogError("Mod22: Geçerli soru yok. TXT dosyası 30 alanlı satırlardan oluşmalı.");
|
|||
|
|
enabled = false;
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
PrepareUI();
|
|||
|
|
BindButtons();
|
|||
|
|
ResetQuestionPool();
|
|||
|
|
|
|||
|
|
UpdateLanguageUI();
|
|||
|
|
UpdateScoreUI();
|
|||
|
|
UpdateComboUI();
|
|||
|
|
UpdateTimerUI();
|
|||
|
|
UpdateExtraStatsUI();
|
|||
|
|
|
|||
|
|
NextQuestion();
|
|||
|
|
|
|||
|
|
Debug.Log("Mod22 Diyalog Dili: " + screenLangIndex + " / " + langNames[screenLangIndex]);
|
|||
|
|
Debug.Log("Mod22 Şık Dili: " + optionLangIndex + " / " + langNames[optionLangIndex]);
|
|||
|
|
Debug.Log("Mod22 Toplam Soru: " + allQuestions.Count);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void Update()
|
|||
|
|
{
|
|||
|
|
if (gameOver)
|
|||
|
|
return;
|
|||
|
|
|
|||
|
|
timeLeft -= Time.deltaTime;
|
|||
|
|
|
|||
|
|
if (timeLeft <= 0f)
|
|||
|
|
{
|
|||
|
|
timeLeft = 0f;
|
|||
|
|
UpdateTimerUI();
|
|||
|
|
GameOver();
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
UpdateTimerUI();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
bool ValidateRequiredReferences()
|
|||
|
|
{
|
|||
|
|
if (dialogueText == null)
|
|||
|
|
{
|
|||
|
|
Debug.LogError("Mod22: dialogueText atanmadı.");
|
|||
|
|
enabled = false;
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (answerButtons == null || answerButtons.Length < 4)
|
|||
|
|
{
|
|||
|
|
Debug.LogError("Mod22: En az 4 answerButtons atanmalı.");
|
|||
|
|
enabled = false;
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (answerTexts == null || answerTexts.Length < 4)
|
|||
|
|
{
|
|||
|
|
Debug.LogError("Mod22: En az 4 answerTexts atanmalı.");
|
|||
|
|
enabled = false;
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
for (int i = 0; i < 4; i++)
|
|||
|
|
{
|
|||
|
|
if (answerButtons[i] == null)
|
|||
|
|
{
|
|||
|
|
Debug.LogError("Mod22: answerButtons[" + i + "] boş.");
|
|||
|
|
enabled = false;
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (answerTexts[i] == null)
|
|||
|
|
{
|
|||
|
|
Debug.LogError("Mod22: answerTexts[" + i + "] boş.");
|
|||
|
|
enabled = false;
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// TXT FORMAT:
|
|||
|
|
// 0-5 diyalog:
|
|||
|
|
// trDialogue|enDialogue|esDialogue|deDialogue|frDialogue|ptDialogue
|
|||
|
|
//
|
|||
|
|
// 6-29 cevap şıkları:
|
|||
|
|
// trCorrect|trWrong1|trWrong2|trWrong3
|
|||
|
|
// enCorrect|enWrong1|enWrong2|enWrong3
|
|||
|
|
// esCorrect|esWrong1|esWrong2|esWrong3
|
|||
|
|
// deCorrect|deWrong1|deWrong2|deWrong3
|
|||
|
|
// frCorrect|frWrong1|frWrong2|frWrong3
|
|||
|
|
// ptCorrect|ptWrong1|ptWrong2|ptWrong3
|
|||
|
|
|
|||
|
|
void LoadQuestions()
|
|||
|
|
{
|
|||
|
|
allQuestions.Clear();
|
|||
|
|
|
|||
|
|
TextAsset txt = wordFile;
|
|||
|
|
|
|||
|
|
if (txt == null)
|
|||
|
|
txt = Resources.Load<TextAsset>(wordsResourcePath);
|
|||
|
|
|
|||
|
|
if (txt == null)
|
|||
|
|
{
|
|||
|
|
Debug.LogError("Mod22: TXT bulunamadı. Şuraya koy: Assets/Resources/" + wordsResourcePath + ".txt");
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
string[] lines = txt.text.Split(
|
|||
|
|
new[] { '\n', '\r' },
|
|||
|
|
System.StringSplitOptions.RemoveEmptyEntries
|
|||
|
|
);
|
|||
|
|
|
|||
|
|
int skipped = 0;
|
|||
|
|
|
|||
|
|
for (int i = 0; i < lines.Length; i++)
|
|||
|
|
{
|
|||
|
|
string line = lines[i].Trim();
|
|||
|
|
|
|||
|
|
if (string.IsNullOrWhiteSpace(line))
|
|||
|
|
continue;
|
|||
|
|
|
|||
|
|
if (line.StartsWith("#"))
|
|||
|
|
continue;
|
|||
|
|
|
|||
|
|
string[] p = SplitLineSmart(line);
|
|||
|
|
|
|||
|
|
if (p.Length < 30)
|
|||
|
|
{
|
|||
|
|
skipped++;
|
|||
|
|
Debug.LogWarning("Mod22 TXT eksik satır atlandı. Satır: " + (i + 1) + " Alan sayısı: " + p.Length + " / Gerekli: 30");
|
|||
|
|
continue;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
DialogueEntry entry = new DialogueEntry();
|
|||
|
|
entry.sourceLine = i + 1;
|
|||
|
|
|
|||
|
|
bool valid = true;
|
|||
|
|
|
|||
|
|
for (int l = 0; l < 6; l++)
|
|||
|
|
{
|
|||
|
|
entry.dialogues[l] = CleanField(p[l]);
|
|||
|
|
|
|||
|
|
if (string.IsNullOrWhiteSpace(entry.dialogues[l]))
|
|||
|
|
valid = false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
for (int q = 0; q < 24; q++)
|
|||
|
|
{
|
|||
|
|
entry.options[q] = CleanField(p[6 + q]);
|
|||
|
|
|
|||
|
|
if (string.IsNullOrWhiteSpace(entry.options[q]))
|
|||
|
|
valid = false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (!valid)
|
|||
|
|
{
|
|||
|
|
skipped++;
|
|||
|
|
Debug.LogWarning("Mod22 TXT boş alan içerdiği için satır atlandı. Satır: " + (i + 1));
|
|||
|
|
continue;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
allQuestions.Add(entry);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
Debug.Log("Mod22 yüklenen soru sayısı: " + allQuestions.Count + " | Atlanan satır: " + skipped);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
string[] SplitLineSmart(string line)
|
|||
|
|
{
|
|||
|
|
if (line.Contains("|"))
|
|||
|
|
return line.Split('|');
|
|||
|
|
|
|||
|
|
if (line.Contains("\t"))
|
|||
|
|
return line.Split('\t');
|
|||
|
|
|
|||
|
|
return line.Split(',');
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
string CleanField(string s)
|
|||
|
|
{
|
|||
|
|
if (string.IsNullOrEmpty(s))
|
|||
|
|
return "";
|
|||
|
|
|
|||
|
|
return s.Trim()
|
|||
|
|
.Trim('"')
|
|||
|
|
.Trim()
|
|||
|
|
.Replace("\\n", "\n")
|
|||
|
|
.Replace("[blank]", "____")
|
|||
|
|
.Replace(" ", " ");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void ResolveLanguages()
|
|||
|
|
{
|
|||
|
|
if (forcedQuestionLanguageIndex >= 0 && forcedQuestionLanguageIndex <= 5)
|
|||
|
|
screenLangIndex = forcedQuestionLanguageIndex;
|
|||
|
|
else
|
|||
|
|
screenLangIndex = PlayerPrefs.GetInt("QuestionLangID", 1);
|
|||
|
|
|
|||
|
|
if (forcedAnswerLanguageIndex >= 0 && forcedAnswerLanguageIndex <= 5)
|
|||
|
|
optionLangIndex = forcedAnswerLanguageIndex;
|
|||
|
|
else
|
|||
|
|
optionLangIndex = PlayerPrefs.GetInt("AnswerLangID", 0);
|
|||
|
|
|
|||
|
|
screenLangIndex = ClampLanguage(screenLangIndex, 1);
|
|||
|
|
optionLangIndex = ClampLanguage(optionLangIndex, 0);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
int ClampLanguage(int value, int fallback)
|
|||
|
|
{
|
|||
|
|
if (value < 0 || value > 5)
|
|||
|
|
return fallback;
|
|||
|
|
|
|||
|
|
return value;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public void RefreshLanguagesFromPrefs()
|
|||
|
|
{
|
|||
|
|
ResolveLanguages();
|
|||
|
|
UpdateLanguageUI();
|
|||
|
|
|
|||
|
|
if (currentQuestion != null && !gameOver)
|
|||
|
|
RefreshCurrentQuestion();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public void SetQuestionLanguage(int id)
|
|||
|
|
{
|
|||
|
|
if (id < 0 || id > 5)
|
|||
|
|
return;
|
|||
|
|
|
|||
|
|
screenLangIndex = id;
|
|||
|
|
|
|||
|
|
PlayerPrefs.SetInt("QuestionLangID", id);
|
|||
|
|
PlayerPrefs.SetString("QuestionLangCode", ToCode(id));
|
|||
|
|
PlayerPrefs.Save();
|
|||
|
|
|
|||
|
|
UpdateLanguageUI();
|
|||
|
|
RefreshCurrentQuestion();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public void SetAnswerLanguage(int id)
|
|||
|
|
{
|
|||
|
|
if (id < 0 || id > 5)
|
|||
|
|
return;
|
|||
|
|
|
|||
|
|
optionLangIndex = id;
|
|||
|
|
|
|||
|
|
PlayerPrefs.SetInt("AnswerLangID", id);
|
|||
|
|
PlayerPrefs.SetString("AnswerLangCode", ToCode(id));
|
|||
|
|
PlayerPrefs.Save();
|
|||
|
|
|
|||
|
|
UpdateLanguageUI();
|
|||
|
|
RefreshCurrentQuestion();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
string ToCode(int id)
|
|||
|
|
{
|
|||
|
|
switch (id)
|
|||
|
|
{
|
|||
|
|
case 0: return "tr";
|
|||
|
|
case 1: return "en";
|
|||
|
|
case 2: return "es";
|
|||
|
|
case 3: return "de";
|
|||
|
|
case 4: return "fr";
|
|||
|
|
case 5: return "pt";
|
|||
|
|
default: return "en";
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void UpdateLanguageUI()
|
|||
|
|
{
|
|||
|
|
if (languageText != null)
|
|||
|
|
{
|
|||
|
|
languageText.text =
|
|||
|
|
GetText("dialogueLabel").ToUpper() + ": " + langNames[screenLangIndex] +
|
|||
|
|
" | " + GetText("answerLabel").ToUpper() + ": " + langNames[optionLangIndex];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (titleText != null)
|
|||
|
|
titleText.text = GetTitleText();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
string GetTitleText()
|
|||
|
|
{
|
|||
|
|
switch (optionLangIndex)
|
|||
|
|
{
|
|||
|
|
case 0: return "Eksik Cevabı Tamamla";
|
|||
|
|
case 1: return "Complete the Missing Reply";
|
|||
|
|
case 2: return "Completa la respuesta faltante";
|
|||
|
|
case 3: return "Ergänze die fehlende Antwort";
|
|||
|
|
case 4: return "Complète la réponse manquante";
|
|||
|
|
case 5: return "Complete a resposta que falta";
|
|||
|
|
default: return "Complete the Missing Reply";
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
string GetText(string key)
|
|||
|
|
{
|
|||
|
|
int lang = optionLangIndex;
|
|||
|
|
|
|||
|
|
if (key == "choose")
|
|||
|
|
{
|
|||
|
|
if (lang == 0) return "BİR CEVAP SEÇ";
|
|||
|
|
if (lang == 1) return "CHOOSE AN ANSWER";
|
|||
|
|
if (lang == 2) return "ELIGE UNA RESPUESTA";
|
|||
|
|
if (lang == 3) return "WÄHLE EINE ANTWORT";
|
|||
|
|
if (lang == 4) return "CHOISIS UNE RÉPONSE";
|
|||
|
|
if (lang == 5) return "ESCOLHA UMA RESPOSTA";
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (key == "correct")
|
|||
|
|
{
|
|||
|
|
if (lang == 0) return "DOĞRU";
|
|||
|
|
if (lang == 1) return "CORRECT";
|
|||
|
|
if (lang == 2) return "CORRECTO";
|
|||
|
|
if (lang == 3) return "RICHTIG";
|
|||
|
|
if (lang == 4) return "CORRECT";
|
|||
|
|
if (lang == 5) return "CORRETO";
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (key == "wrong")
|
|||
|
|
{
|
|||
|
|
if (lang == 0) return "YANLIŞ";
|
|||
|
|
if (lang == 1) return "WRONG";
|
|||
|
|
if (lang == 2) return "INCORRECTO";
|
|||
|
|
if (lang == 3) return "FALSCH";
|
|||
|
|
if (lang == 4) return "FAUX";
|
|||
|
|
if (lang == 5) return "ERRADO";
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (key == "correctAnswer")
|
|||
|
|
{
|
|||
|
|
if (lang == 0) return "Doğru cevap";
|
|||
|
|
if (lang == 1) return "Correct answer";
|
|||
|
|
if (lang == 2) return "Respuesta correcta";
|
|||
|
|
if (lang == 3) return "Richtige Antwort";
|
|||
|
|
if (lang == 4) return "Bonne réponse";
|
|||
|
|
if (lang == 5) return "Resposta correta";
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (key == "dialogueLabel")
|
|||
|
|
{
|
|||
|
|
if (screenLangIndex == 0) return "Diyalog";
|
|||
|
|
if (screenLangIndex == 1) return "Dialogue";
|
|||
|
|
if (screenLangIndex == 2) return "Diálogo";
|
|||
|
|
if (screenLangIndex == 3) return "Dialog";
|
|||
|
|
if (screenLangIndex == 4) return "Dialogue";
|
|||
|
|
if (screenLangIndex == 5) return "Diálogo";
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (key == "answerLabel")
|
|||
|
|
{
|
|||
|
|
if (lang == 0) return "Cevap";
|
|||
|
|
if (lang == 1) return "Answer";
|
|||
|
|
if (lang == 2) return "Respuesta";
|
|||
|
|
if (lang == 3) return "Antwort";
|
|||
|
|
if (lang == 4) return "Réponse";
|
|||
|
|
if (lang == 5) return "Resposta";
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (key == "skipped")
|
|||
|
|
{
|
|||
|
|
if (lang == 0) return "GEÇİLDİ";
|
|||
|
|
if (lang == 1) return "SKIPPED";
|
|||
|
|
if (lang == 2) return "SALTADO";
|
|||
|
|
if (lang == 3) return "ÜBERSPRUNGEN";
|
|||
|
|
if (lang == 4) return "PASSÉ";
|
|||
|
|
if (lang == 5) return "PULADO";
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (key == "hint")
|
|||
|
|
{
|
|||
|
|
if (lang == 0) return "İPUCU KULLANILDI";
|
|||
|
|
if (lang == 1) return "HINT USED";
|
|||
|
|
if (lang == 2) return "PISTA USADA";
|
|||
|
|
if (lang == 3) return "HINWEIS GENUTZT";
|
|||
|
|
if (lang == 4) return "INDICE UTILISÉ";
|
|||
|
|
if (lang == 5) return "DICA USADA";
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return key;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void PrepareUI()
|
|||
|
|
{
|
|||
|
|
if (dialogueText != null)
|
|||
|
|
{
|
|||
|
|
dialogueText.alignment = TextAlignmentOptions.Center;
|
|||
|
|
dialogueText.textWrappingMode = TextWrappingModes.Normal;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (feedbackText != null)
|
|||
|
|
{
|
|||
|
|
feedbackText.text = "";
|
|||
|
|
feedbackText.alignment = TextAlignmentOptions.Center;
|
|||
|
|
feedbackText.textWrappingMode = TextWrappingModes.Normal;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
originalButtonScales = new Vector3[answerButtons.Length];
|
|||
|
|
originalButtonPositions = new Vector3[answerButtons.Length];
|
|||
|
|
|
|||
|
|
for (int i = 0; i < answerButtons.Length; i++)
|
|||
|
|
{
|
|||
|
|
if (answerButtons[i] == null)
|
|||
|
|
continue;
|
|||
|
|
|
|||
|
|
originalButtonScales[i] = answerButtons[i].transform.localScale;
|
|||
|
|
originalButtonPositions[i] = answerButtons[i].transform.localPosition;
|
|||
|
|
|
|||
|
|
answerButtons[i].transition = Selectable.Transition.None;
|
|||
|
|
|
|||
|
|
if (answerButtons[i].image != null)
|
|||
|
|
answerButtons[i].image.color = normalButtonColor;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
HideCooldownTexts();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void HideCooldownTexts()
|
|||
|
|
{
|
|||
|
|
if (extraTimeCooldownText != null)
|
|||
|
|
extraTimeCooldownText.gameObject.SetActive(false);
|
|||
|
|
|
|||
|
|
if (extraHintCooldownText != null)
|
|||
|
|
extraHintCooldownText.gameObject.SetActive(false);
|
|||
|
|
|
|||
|
|
if (extraSkipCooldownText != null)
|
|||
|
|
extraSkipCooldownText.gameObject.SetActive(false);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void BindButtons()
|
|||
|
|
{
|
|||
|
|
if (submitButton != null)
|
|||
|
|
{
|
|||
|
|
submitButton.onClick.RemoveAllListeners();
|
|||
|
|
submitButton.onClick.AddListener(OnSubmit);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (backButton != null)
|
|||
|
|
{
|
|||
|
|
backButton.onClick.RemoveAllListeners();
|
|||
|
|
backButton.onClick.AddListener(() =>
|
|||
|
|
{
|
|||
|
|
SaveProgressOnly();
|
|||
|
|
SceneManager.LoadScene(backSceneName);
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (extraTimeButton != null)
|
|||
|
|
{
|
|||
|
|
extraTimeButton.onClick.RemoveAllListeners();
|
|||
|
|
extraTimeButton.onClick.AddListener(OnExtraTime);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (extraHintButton != null)
|
|||
|
|
{
|
|||
|
|
extraHintButton.onClick.RemoveAllListeners();
|
|||
|
|
extraHintButton.onClick.AddListener(OnExtraHint);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (extraSkipButton != null)
|
|||
|
|
{
|
|||
|
|
extraSkipButton.onClick.RemoveAllListeners();
|
|||
|
|
extraSkipButton.onClick.AddListener(OnExtraSkip);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
for (int i = 0; i < answerButtons.Length; i++)
|
|||
|
|
{
|
|||
|
|
int index = i;
|
|||
|
|
|
|||
|
|
if (answerButtons[i] == null)
|
|||
|
|
continue;
|
|||
|
|
|
|||
|
|
answerButtons[i].onClick.RemoveAllListeners();
|
|||
|
|
answerButtons[i].onClick.AddListener(() => SelectAnswer(index));
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void ResetQuestionPool()
|
|||
|
|
{
|
|||
|
|
questionPool.Clear();
|
|||
|
|
questionPool.AddRange(allQuestions);
|
|||
|
|
Shuffle(questionPool);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void NextQuestion()
|
|||
|
|
{
|
|||
|
|
if (gameOver)
|
|||
|
|
return;
|
|||
|
|
|
|||
|
|
if (questionPool.Count <= 0)
|
|||
|
|
ResetQuestionPool();
|
|||
|
|
|
|||
|
|
currentQuestion = questionPool[0];
|
|||
|
|
questionPool.RemoveAt(0);
|
|||
|
|
|
|||
|
|
questionNumber++;
|
|||
|
|
RefreshCurrentQuestion();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void RefreshCurrentQuestion()
|
|||
|
|
{
|
|||
|
|
if (currentQuestion == null)
|
|||
|
|
return;
|
|||
|
|
|
|||
|
|
waitingNextQuestion = false;
|
|||
|
|
selectedAnswer = -1;
|
|||
|
|
correctAnswerIndex = -1;
|
|||
|
|
|
|||
|
|
ResetButtons();
|
|||
|
|
|
|||
|
|
string dialogueValue = currentQuestion.dialogues[screenLangIndex];
|
|||
|
|
string correctAnswer = GetOption(currentQuestion, optionLangIndex, 0);
|
|||
|
|
|
|||
|
|
if (dialogueText != null)
|
|||
|
|
dialogueText.text = GetText("dialogueLabel") + ":\n" + dialogueValue;
|
|||
|
|
|
|||
|
|
List<string> options = new List<string>();
|
|||
|
|
|
|||
|
|
for (int i = 0; i < 4; i++)
|
|||
|
|
{
|
|||
|
|
string option = GetOption(currentQuestion, optionLangIndex, i);
|
|||
|
|
|
|||
|
|
if (!string.IsNullOrWhiteSpace(option) && !options.Contains(option))
|
|||
|
|
options.Add(option);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
while (options.Count < 4)
|
|||
|
|
options.Add("?");
|
|||
|
|
|
|||
|
|
Shuffle(options);
|
|||
|
|
|
|||
|
|
correctAnswerIndex = options.IndexOf(correctAnswer);
|
|||
|
|
|
|||
|
|
if (correctAnswerIndex < 0)
|
|||
|
|
{
|
|||
|
|
correctAnswerIndex = 0;
|
|||
|
|
options[0] = correctAnswer;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
for (int i = 0; i < 4; i++)
|
|||
|
|
{
|
|||
|
|
if (answerTexts[i] != null)
|
|||
|
|
answerTexts[i].text = options[i];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (feedbackText != null)
|
|||
|
|
feedbackText.text = "";
|
|||
|
|
|
|||
|
|
if (submitButton != null)
|
|||
|
|
submitButton.interactable = true;
|
|||
|
|
|
|||
|
|
UpdateExtraStatsUI();
|
|||
|
|
StartCoroutine(DialoguePopAnim());
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
string GetOption(DialogueEntry entry, int langIndex, int optionIndex)
|
|||
|
|
{
|
|||
|
|
int index = langIndex * 4 + optionIndex;
|
|||
|
|
|
|||
|
|
if (index < 0 || index >= entry.options.Length)
|
|||
|
|
return "";
|
|||
|
|
|
|||
|
|
return entry.options[index];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void ResetButtons()
|
|||
|
|
{
|
|||
|
|
for (int i = 0; i < answerButtons.Length; i++)
|
|||
|
|
{
|
|||
|
|
if (answerButtons[i] == null)
|
|||
|
|
continue;
|
|||
|
|
|
|||
|
|
answerButtons[i].interactable = true;
|
|||
|
|
answerButtons[i].transform.localScale = originalButtonScales[i];
|
|||
|
|
answerButtons[i].transform.localPosition = originalButtonPositions[i];
|
|||
|
|
|
|||
|
|
if (answerButtons[i].image != null)
|
|||
|
|
answerButtons[i].image.color = normalButtonColor;
|
|||
|
|
|
|||
|
|
if (i < answerTexts.Length && answerTexts[i] != null)
|
|||
|
|
answerTexts[i].text = "";
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void SelectAnswer(int index)
|
|||
|
|
{
|
|||
|
|
if (gameOver || waitingNextQuestion)
|
|||
|
|
return;
|
|||
|
|
|
|||
|
|
if (index < 0 || index >= answerButtons.Length)
|
|||
|
|
return;
|
|||
|
|
|
|||
|
|
if (answerButtons[index] == null || !answerButtons[index].interactable)
|
|||
|
|
return;
|
|||
|
|
|
|||
|
|
selectedAnswer = index;
|
|||
|
|
|
|||
|
|
for (int i = 0; i < answerButtons.Length; i++)
|
|||
|
|
{
|
|||
|
|
if (answerButtons[i] == null)
|
|||
|
|
continue;
|
|||
|
|
|
|||
|
|
if (answerButtons[i].image != null && answerButtons[i].interactable)
|
|||
|
|
answerButtons[i].image.color = normalButtonColor;
|
|||
|
|
|
|||
|
|
answerButtons[i].transform.localScale = originalButtonScales[i];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (answerButtons[index].image != null)
|
|||
|
|
answerButtons[index].image.color = selectedButtonColor;
|
|||
|
|
|
|||
|
|
answerButtons[index].transform.localScale = originalButtonScales[index] * 0.96f;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void OnSubmit()
|
|||
|
|
{
|
|||
|
|
if (gameOver || waitingNextQuestion)
|
|||
|
|
return;
|
|||
|
|
|
|||
|
|
if (selectedAnswer < 0)
|
|||
|
|
{
|
|||
|
|
ShowFeedback(GetText("choose"), wrongButtonColor);
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
waitingNextQuestion = true;
|
|||
|
|
|
|||
|
|
if (submitButton != null)
|
|||
|
|
submitButton.interactable = false;
|
|||
|
|
|
|||
|
|
for (int i = 0; i < answerButtons.Length; i++)
|
|||
|
|
{
|
|||
|
|
if (answerButtons[i] != null)
|
|||
|
|
answerButtons[i].interactable = false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (selectedAnswer == correctAnswerIndex)
|
|||
|
|
CorrectAnswer();
|
|||
|
|
else
|
|||
|
|
WrongAnswer();
|
|||
|
|
|
|||
|
|
UpdateScoreUI();
|
|||
|
|
UpdateComboUI();
|
|||
|
|
UpdateExtraStatsUI();
|
|||
|
|
SaveProgressOnly();
|
|||
|
|
|
|||
|
|
StartCoroutine(NextQuestionDelay());
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void CorrectAnswer()
|
|||
|
|
{
|
|||
|
|
if (answerButtons[selectedAnswer].image != null)
|
|||
|
|
answerButtons[selectedAnswer].image.color = correctButtonColor;
|
|||
|
|
|
|||
|
|
combo++;
|
|||
|
|
correctCount++;
|
|||
|
|
|
|||
|
|
if (combo > bestComboThisRun)
|
|||
|
|
bestComboThisRun = combo;
|
|||
|
|
|
|||
|
|
int earned = Mathf.RoundToInt(basePoints * GetComboMultiplier(combo));
|
|||
|
|
|
|||
|
|
score += earned;
|
|||
|
|
timeLeft += correctTimeBonus;
|
|||
|
|
|
|||
|
|
ShowFeedback(GetText("correct") + " +" + earned, correctButtonColor);
|
|||
|
|
StartCoroutine(ButtonPop(answerButtons[selectedAnswer]));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void WrongAnswer()
|
|||
|
|
{
|
|||
|
|
if (answerButtons[selectedAnswer].image != null)
|
|||
|
|
answerButtons[selectedAnswer].image.color = wrongButtonColor;
|
|||
|
|
|
|||
|
|
if (correctAnswerIndex >= 0 && correctAnswerIndex < answerButtons.Length)
|
|||
|
|
{
|
|||
|
|
if (answerButtons[correctAnswerIndex].image != null)
|
|||
|
|
answerButtons[correctAnswerIndex].image.color = correctButtonColor;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
wrongCount++;
|
|||
|
|
combo = 0;
|
|||
|
|
|
|||
|
|
score -= wrongPenalty;
|
|||
|
|
|
|||
|
|
if (score < 0)
|
|||
|
|
score = 0;
|
|||
|
|
|
|||
|
|
if (wrongTimePenalty > 0f)
|
|||
|
|
{
|
|||
|
|
timeLeft -= wrongTimePenalty;
|
|||
|
|
|
|||
|
|
if (timeLeft < 0f)
|
|||
|
|
timeLeft = 0f;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
string correctText = "";
|
|||
|
|
|
|||
|
|
if (correctAnswerIndex >= 0 && correctAnswerIndex < answerTexts.Length && answerTexts[correctAnswerIndex] != null)
|
|||
|
|
correctText = answerTexts[correctAnswerIndex].text;
|
|||
|
|
|
|||
|
|
ShowFeedback(GetText("wrong") + "\n" + GetText("correctAnswer") + ": " + correctText, wrongButtonColor);
|
|||
|
|
StartCoroutine(ButtonShake(answerButtons[selectedAnswer]));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
IEnumerator NextQuestionDelay()
|
|||
|
|
{
|
|||
|
|
yield return new WaitForSeconds(nextQuestionDelay);
|
|||
|
|
|
|||
|
|
if (!gameOver)
|
|||
|
|
NextQuestion();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void OnExtraTime()
|
|||
|
|
{
|
|||
|
|
if (!extraTimeReady || gameOver)
|
|||
|
|
return;
|
|||
|
|
|
|||
|
|
timeLeft += extraTimeAmount;
|
|||
|
|
extraTimeReady = false;
|
|||
|
|
|
|||
|
|
if (extraTimeButton != null)
|
|||
|
|
extraTimeButton.interactable = false;
|
|||
|
|
|
|||
|
|
StartCoroutine(Cooldown(extraTimeCooldownText, extraTimeButton, () => extraTimeReady = true));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void OnExtraHint()
|
|||
|
|
{
|
|||
|
|
if (!extraHintReady || gameOver || waitingNextQuestion)
|
|||
|
|
return;
|
|||
|
|
|
|||
|
|
int removed = 0;
|
|||
|
|
|
|||
|
|
for (int i = 0; i < answerButtons.Length && removed < 2; i++)
|
|||
|
|
{
|
|||
|
|
if (i == correctAnswerIndex)
|
|||
|
|
continue;
|
|||
|
|
|
|||
|
|
if (i == selectedAnswer)
|
|||
|
|
continue;
|
|||
|
|
|
|||
|
|
if (answerButtons[i] == null)
|
|||
|
|
continue;
|
|||
|
|
|
|||
|
|
if (!answerButtons[i].interactable)
|
|||
|
|
continue;
|
|||
|
|
|
|||
|
|
answerButtons[i].interactable = false;
|
|||
|
|
|
|||
|
|
if (answerButtons[i].image != null)
|
|||
|
|
answerButtons[i].image.color = disabledButtonColor;
|
|||
|
|
|
|||
|
|
if (answerTexts != null && i < answerTexts.Length && answerTexts[i] != null)
|
|||
|
|
answerTexts[i].text = "—";
|
|||
|
|
|
|||
|
|
removed++;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
ShowFeedback(GetText("hint"), Color.white);
|
|||
|
|
|
|||
|
|
extraHintReady = false;
|
|||
|
|
|
|||
|
|
if (extraHintButton != null)
|
|||
|
|
extraHintButton.interactable = false;
|
|||
|
|
|
|||
|
|
StartCoroutine(Cooldown(extraHintCooldownText, extraHintButton, () => extraHintReady = true));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void OnExtraSkip()
|
|||
|
|
{
|
|||
|
|
if (!extraSkipReady || gameOver || waitingNextQuestion)
|
|||
|
|
return;
|
|||
|
|
|
|||
|
|
combo = 0;
|
|||
|
|
UpdateComboUI();
|
|||
|
|
|
|||
|
|
ShowFeedback(GetText("skipped"), Color.white);
|
|||
|
|
|
|||
|
|
NextQuestion();
|
|||
|
|
|
|||
|
|
extraSkipReady = false;
|
|||
|
|
|
|||
|
|
if (extraSkipButton != null)
|
|||
|
|
extraSkipButton.interactable = false;
|
|||
|
|
|
|||
|
|
StartCoroutine(Cooldown(extraSkipCooldownText, extraSkipButton, () => extraSkipReady = true));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
IEnumerator Cooldown(TMP_Text label, Button button, System.Action done)
|
|||
|
|
{
|
|||
|
|
float t = cooldownDuration;
|
|||
|
|
|
|||
|
|
if (label != null)
|
|||
|
|
label.gameObject.SetActive(true);
|
|||
|
|
|
|||
|
|
while (t > 0)
|
|||
|
|
{
|
|||
|
|
if (label != null)
|
|||
|
|
label.text = Mathf.CeilToInt(t).ToString();
|
|||
|
|
|
|||
|
|
t -= Time.deltaTime;
|
|||
|
|
yield return null;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (label != null)
|
|||
|
|
{
|
|||
|
|
label.text = "";
|
|||
|
|
label.gameObject.SetActive(false);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (button != null)
|
|||
|
|
button.interactable = true;
|
|||
|
|
|
|||
|
|
done?.Invoke();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void SaveProgressOnly()
|
|||
|
|
{
|
|||
|
|
PlayerPrefs.SetInt("Mod22Skor", score);
|
|||
|
|
PlayerPrefs.SetInt("Mod22Score", score);
|
|||
|
|
PlayerPrefs.SetInt("Mod22Correct", correctCount);
|
|||
|
|
PlayerPrefs.SetInt("Mod22Wrong", wrongCount);
|
|||
|
|
|
|||
|
|
PlayerPrefs.SetInt(modKey + "_LastScore", score);
|
|||
|
|
PlayerPrefs.SetInt(modKey + "_Correct", correctCount);
|
|||
|
|
PlayerPrefs.SetInt(modKey + "_Wrong", wrongCount);
|
|||
|
|
PlayerPrefs.SetInt(modKey + "_LastCombo", combo);
|
|||
|
|
PlayerPrefs.SetInt(modKey + "_BestComboRun", bestComboThisRun);
|
|||
|
|
PlayerPrefs.SetInt(modKey + "_LastTimeLeft", Mathf.CeilToInt(timeLeft));
|
|||
|
|
|
|||
|
|
int total = correctCount + wrongCount;
|
|||
|
|
int accuracy = total > 0 ? Mathf.RoundToInt((correctCount / (float)total) * 100f) : 0;
|
|||
|
|
|
|||
|
|
PlayerPrefs.SetInt(modKey + "_LastAccuracy", accuracy);
|
|||
|
|
|
|||
|
|
if (score > PlayerPrefs.GetInt(modKey + "_MaxScore", 0))
|
|||
|
|
PlayerPrefs.SetInt(modKey + "_MaxScore", score);
|
|||
|
|
|
|||
|
|
if (score > PlayerPrefs.GetInt("Mod22LeaderScore", 0))
|
|||
|
|
PlayerPrefs.SetInt("Mod22LeaderScore", score);
|
|||
|
|
|
|||
|
|
if (score > PlayerPrefs.GetInt("Mod22BestScore", 0))
|
|||
|
|
PlayerPrefs.SetInt("Mod22BestScore", score);
|
|||
|
|
|
|||
|
|
if (bestComboThisRun > PlayerPrefs.GetInt(modKey + "_BestCombo", 0))
|
|||
|
|
PlayerPrefs.SetInt(modKey + "_BestCombo", bestComboThisRun);
|
|||
|
|
|
|||
|
|
PlayerPrefs.Save();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void GameOver()
|
|||
|
|
{
|
|||
|
|
if (gameOver)
|
|||
|
|
return;
|
|||
|
|
|
|||
|
|
gameOver = true;
|
|||
|
|
|
|||
|
|
SaveProgressOnly();
|
|||
|
|
|
|||
|
|
PlayerPrefs.SetString("LastPlayedMod", modKey);
|
|||
|
|
|
|||
|
|
PlayerPrefs.SetInt(modKey + "_TotalCorrect", PlayerPrefs.GetInt(modKey + "_TotalCorrect", 0) + correctCount);
|
|||
|
|
PlayerPrefs.SetInt(modKey + "_TotalWrong", PlayerPrefs.GetInt(modKey + "_TotalWrong", 0) + wrongCount);
|
|||
|
|
PlayerPrefs.SetInt(modKey + "_PlayCount", PlayerPrefs.GetInt(modKey + "_PlayCount", 0) + 1);
|
|||
|
|
PlayerPrefs.SetInt("TotalScore", PlayerPrefs.GetInt("TotalScore", 0) + score);
|
|||
|
|
|
|||
|
|
PlayerPrefs.Save();
|
|||
|
|
|
|||
|
|
SceneManager.LoadScene(resultSceneName);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void UpdateScoreUI()
|
|||
|
|
{
|
|||
|
|
if (scoreText != null)
|
|||
|
|
scoreText.text = score.ToString();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void UpdateComboUI()
|
|||
|
|
{
|
|||
|
|
if (comboText != null)
|
|||
|
|
comboText.text = combo + "x";
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void UpdateTimerUI()
|
|||
|
|
{
|
|||
|
|
if (timerText == null)
|
|||
|
|
return;
|
|||
|
|
|
|||
|
|
timerText.text = Mathf.CeilToInt(timeLeft).ToString();
|
|||
|
|
|
|||
|
|
if (timeLeft <= 10f)
|
|||
|
|
timerText.color = Color.red;
|
|||
|
|
else
|
|||
|
|
timerText.color = Color.white;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void UpdateExtraStatsUI()
|
|||
|
|
{
|
|||
|
|
int total = correctCount + wrongCount;
|
|||
|
|
int accuracy = total > 0 ? Mathf.RoundToInt((correctCount / (float)total) * 100f) : 0;
|
|||
|
|
|
|||
|
|
if (questionCounterText != null)
|
|||
|
|
questionCounterText.text = questionNumber + " / " + allQuestions.Count;
|
|||
|
|
|
|||
|
|
if (accuracyText != null)
|
|||
|
|
accuracyText.text = "%" + accuracy;
|
|||
|
|
|
|||
|
|
if (streakText != null)
|
|||
|
|
streakText.text = bestComboThisRun.ToString();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void ShowFeedback(string msg, Color color)
|
|||
|
|
{
|
|||
|
|
if (feedbackText == null)
|
|||
|
|
return;
|
|||
|
|
|
|||
|
|
feedbackText.text = msg;
|
|||
|
|
feedbackText.color = FullAlpha(color);
|
|||
|
|
|
|||
|
|
StopCoroutine(nameof(FeedbackAnim));
|
|||
|
|
StartCoroutine(nameof(FeedbackAnim));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
float GetComboMultiplier(int c)
|
|||
|
|
{
|
|||
|
|
if (c >= 8)
|
|||
|
|
return mult_8plus;
|
|||
|
|
|
|||
|
|
if (c >= 5)
|
|||
|
|
return mult_5to7;
|
|||
|
|
|
|||
|
|
if (c >= 3)
|
|||
|
|
return mult_3to4;
|
|||
|
|
|
|||
|
|
return mult_1to2;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
IEnumerator FeedbackAnim()
|
|||
|
|
{
|
|||
|
|
if (feedbackText == null)
|
|||
|
|
yield break;
|
|||
|
|
|
|||
|
|
Vector3 normal = Vector3.one;
|
|||
|
|
Vector3 big = Vector3.one * 1.15f;
|
|||
|
|
|
|||
|
|
feedbackText.transform.localScale = normal;
|
|||
|
|
|
|||
|
|
float t = 0;
|
|||
|
|
|
|||
|
|
while (t < 1)
|
|||
|
|
{
|
|||
|
|
t += Time.deltaTime / 0.15f;
|
|||
|
|
feedbackText.transform.localScale = Vector3.Lerp(normal, big, t);
|
|||
|
|
yield return null;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
t = 0;
|
|||
|
|
|
|||
|
|
while (t < 1)
|
|||
|
|
{
|
|||
|
|
t += Time.deltaTime / 0.15f;
|
|||
|
|
feedbackText.transform.localScale = Vector3.Lerp(big, normal, t);
|
|||
|
|
yield return null;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
feedbackText.transform.localScale = normal;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
IEnumerator ButtonPop(Button btn)
|
|||
|
|
{
|
|||
|
|
if (btn == null)
|
|||
|
|
yield break;
|
|||
|
|
|
|||
|
|
Vector3 normal = btn.transform.localScale;
|
|||
|
|
Vector3 big = normal * 1.12f;
|
|||
|
|
|
|||
|
|
float t = 0;
|
|||
|
|
|
|||
|
|
while (t < 1)
|
|||
|
|
{
|
|||
|
|
t += Time.deltaTime / 0.10f;
|
|||
|
|
btn.transform.localScale = Vector3.Lerp(normal, big, t);
|
|||
|
|
yield return null;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
t = 0;
|
|||
|
|
|
|||
|
|
while (t < 1)
|
|||
|
|
{
|
|||
|
|
t += Time.deltaTime / 0.10f;
|
|||
|
|
btn.transform.localScale = Vector3.Lerp(big, normal, t);
|
|||
|
|
yield return null;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
btn.transform.localScale = normal;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
IEnumerator ButtonShake(Button btn)
|
|||
|
|
{
|
|||
|
|
if (btn == null)
|
|||
|
|
yield break;
|
|||
|
|
|
|||
|
|
Vector3 original = btn.transform.localPosition;
|
|||
|
|
|
|||
|
|
float duration = 0.20f;
|
|||
|
|
float elapsed = 0f;
|
|||
|
|
float power = 8f;
|
|||
|
|
|
|||
|
|
while (elapsed < duration)
|
|||
|
|
{
|
|||
|
|
elapsed += Time.deltaTime;
|
|||
|
|
|
|||
|
|
float x = Mathf.Sin(elapsed * 80f) * power;
|
|||
|
|
btn.transform.localPosition = original + new Vector3(x, 0f, 0f);
|
|||
|
|
|
|||
|
|
yield return null;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
btn.transform.localPosition = original;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
IEnumerator DialoguePopAnim()
|
|||
|
|
{
|
|||
|
|
if (dialogueText == null)
|
|||
|
|
yield break;
|
|||
|
|
|
|||
|
|
Vector3 normal = Vector3.one;
|
|||
|
|
Vector3 small = Vector3.one * 0.92f;
|
|||
|
|
|
|||
|
|
dialogueText.transform.localScale = small;
|
|||
|
|
|
|||
|
|
float t = 0;
|
|||
|
|
|
|||
|
|
while (t < 1)
|
|||
|
|
{
|
|||
|
|
t += Time.deltaTime / 0.16f;
|
|||
|
|
dialogueText.transform.localScale = Vector3.Lerp(small, normal, t);
|
|||
|
|
yield return null;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
dialogueText.transform.localScale = normal;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
Color FullAlpha(Color c)
|
|||
|
|
{
|
|||
|
|
c.a = 1f;
|
|||
|
|
return c;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void Shuffle<T>(List<T> list)
|
|||
|
|
{
|
|||
|
|
for (int i = 0; i < list.Count; i++)
|
|||
|
|
{
|
|||
|
|
int rnd = Random.Range(i, list.Count);
|
|||
|
|
|
|||
|
|
T temp = list[i];
|
|||
|
|
list[i] = list[rnd];
|
|||
|
|
list[rnd] = temp;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|