Initial commit: Star of Words Unity project

Snapshot of the existing Unity 6 language-learning word game before any
refactoring. Adds Unity .gitignore and .gitattributes.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
portakal 2026-07-05 15:31:20 +03:00
commit ecb1c9edea
1455 changed files with 933295 additions and 0 deletions

8
Assets/Scripts/2.0.meta Normal file
View file

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: c010e549562230f489cf0bdcea04c3e2
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 59b9a2ac56496444bac7b43b2c8e916d

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 77da8ebed4f07fe4fad686635f694c51

View file

@ -0,0 +1,86 @@
using UnityEngine;
using UnityEngine.UI;
using TMPro;
using UnityEngine.SceneManagement;
using System.Collections.Generic;
public class LanguageSettingsController : MonoBehaviour
{
[Header("━━━ DROPDOWNLAR ━━━━━━━━━━━━━━━━━━━━━━━")]
public TMP_Dropdown questionDropdown;
public TMP_Dropdown answerDropdown;
[Header("━━━ BUTONLAR ━━━━━━━━━━━━━━━━━━━━━━━━━━")]
public Button saveAndBackButton;
[Header("━━━ AUDIO ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")]
public AudioClip clickSound;
public AudioSource sfxSource;
void Start()
{
PopulateDropdowns();
questionDropdown.value = PlayerPrefs.GetInt("QuestionLangID", 1);
answerDropdown.value = PlayerPrefs.GetInt("AnswerLangID", 0);
questionDropdown.RefreshShownValue();
answerDropdown.RefreshShownValue();
saveAndBackButton.onClick.AddListener(() => { PlayClick(); SaveAndBack(); });
}
void PopulateDropdowns()
{
List<string> languageNames = new List<string>
{
"Türkçe", // 0
"English", // 1
"Español", // 2
"Deutsch", // 3
"Français", // 4
"Português" // 5
};
questionDropdown.ClearOptions();
answerDropdown.ClearOptions();
questionDropdown.AddOptions(languageNames);
answerDropdown.AddOptions(languageNames);
}
void SaveAndBack()
{
int qID = questionDropdown.value;
int aID = answerDropdown.value;
PlayerPrefs.SetInt("QuestionLangID", qID);
PlayerPrefs.SetInt("AnswerLangID", aID);
PlayerPrefs.SetString("QuestionLangCode", ToCode(qID));
PlayerPrefs.SetString("AnswerLangCode", ToCode(aID));
PlayerPrefs.SetString("AppLanguage", ToCode(qID));
PlayerPrefs.Save();
SceneManager.LoadScene("Anamen");
}
void PlayClick()
{
if (sfxSource != null && clickSound != null)
sfxSource.PlayOneShot(clickSound);
}
string ToCode(int id)
{
return id switch
{
0 => "tr",
1 => "en",
2 => "es",
3 => "de",
4 => "fr",
5 => "pt",
_ => "en"
};
}
}

View file

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 3cbf52aaa9ea95145b92e9f010db66dd

View file

@ -0,0 +1,11 @@
using UnityEngine;
public enum LanguageType
{
TR = 1,
EN = 2,
ES = 3,
DE = 4,
FR = 5,
PT = 6
}

View file

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 32b83b44bd3dd0d4a8f5186eaf12aeca

View file

@ -0,0 +1,220 @@
using UnityEngine;
using UnityEngine.UI;
using TMPro;
using UnityEngine.SceneManagement;
using System.Collections;
public class LevelSelectController : MonoBehaviour
{
[Header("━━━ UI ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")]
public Button[] levelButtons;
public TMP_Text[] levelNameTexts;
public TMP_Text[] levelScoreTexts;
[Header("━━━ BACK BUTONU ━━━━━━━━━━━━━━━━━━━━━━━")]
public Button backButton;
public string backSceneName = "Anamen";
[Header("━━━ AUDIO ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")]
public AudioSource sfxSource;
public AudioClip clickSound;
[Header("━━━ ANİMASYON ━━━━━━━━━━━━━━━━━━━━━━━━━")]
[Range(0.005f, 0.1f)] public float buttonAniSpeed = 0.02f;
private int langIndex;
private Vector3[] originalScales;
private Vector3[] originalPositions;
// ============================================================
private readonly string[,] levelNames = new string[,]
{
{ "Temel Selamlaşma ve İnsanlar","Basic Greetings & People","Saludos Básicos y Personas","Grundbegrüßungen & Menschen","Salutations de Base & Personnes","Saudações Básicas e Pessoas" },
{ "Günlük Ev Nesneleri","Daily Household Items","Objetos del Hogar Diarios","Tägliche Haushaltsgegenstände","Objets Quotidiens de la Maison","Objetos Domésticos Diários" },
{ "Yiyecekler ve İçecekler","Food & Drinks","Comida y Bebida","Essen & Getränke","Nourriture & Boissons","Comidas e Bebidas" },
{ "Renkler, Şekiller ve Boyutlar","Colors, Shapes & Sizes","Colores, Formas y Tamaños","Farben, Formen & Größen","Couleurs, Formas & Tailles","Cores, Formas e Tamanhos" },
{ "Zaman, Günler ve Mevsimler","Time, Days & Seasons","Tiempo, Días y Estaciones","Zeit, Tage & Jahreszeiten","Temps, Jours & Saisons","Tempo, Dias e Estações" },
{ "Ev İçi Alanlar ve Temizlik","Home Areas & Cleaning","Áreas del Hogar y Limpieza","Hausbereiche & Reinigung","Espaces de Maison & Nettoyage","Áreas da Casa e Limpeza" },
{ "Okul, Eğitim ve Ders Araçları","School, Education & Supplies","Escuela, Educación y Útiles","Schule, Bildung & Materialien","École, Éducation & Fournitures","Escola, Educação e Materiais" },
{ "Vücut Parçaları ve Sağlık","Body Parts & Health","Partes del Cuerpo y Salud","Körperteile & Gesundheit","Parties du Corps & Santé","Partes do Corpo e Saúde" },
{ "Doğa, Hava ve Çevre Unsurları","Nature, Weather & Environment","Naturaleza, Clima y Medio Ambiente","Natur, Wetter & Umwelt","Nature, Météo & Environnement","Natureza, Clima e Meio Ambiente" },
{ "Evcil ve Vahşi Hayvanlar","Pets & Wild Animals","Mascotas y Animales Salvajes","Haustiere & Wildtiere","Animaux Domestiques & Sauvages","Animais Domésticos e Selvagens" },
{ "Ulaşım Araçları ve Trafik","Transportation & Traffic","Transporte y Tráfico","Transport & Verkehr","Transport & Circulation","Transporte e Trânsito" },
{ "Alışveriş ve Mağazalar","Shopping & Stores","Compras y Tiendas","Einkaufen & Geschäfte","Shopping & Magasins","Compras e Lojas" },
{ "Spor Dalları ve Ekipmanları","Sports & Equipment","Deportes y Equipamiento","Sportarten & Ausrüstung","Sports & Équipement","Esportes e Equipamentos" },
{ "Meslekler ve İş Alanları","Jobs & Work Fields","Profesiones y Áreas Laborales","Berufe & Arbeitsfelder","Métiers & Domaines de Travail","Profissões e Áreas de Trabalho" },
{ "Şehir, Yerler ve Binalar","City, Places & Buildings","Ciudad, Lugares y Edificios","Stadt, Orte & Gebäude","Ville, Lieux & Bâtiments","Cidade, Lugares e Edifícios" },
{ "Duygular, Durumlar ve Karakter","Emotions, States & Character","Emociones, Estados y Carácter","Gefühle, Zustände & Charakter","Émotions, États & Caractère","Emoções, Estados e Caráter" },
{ "Seyahat, Tatil ve Turizm","Travel, Vacation & Tourism","Viajes, Vacaciones y Turismo","Reisen, Urlaub & Tourismus","Voyage, Vacances & Tourisme","Viagem, Férias e Turismo" },
{ "Teknoloji, İnternet ve Cihazlar","Technology, Internet & Devices","Tecnología, Internet y Dispositivos","Technologie, Internet & Geräte","Technologie, Internet & Appareils","Tecnologia, Internet e Dispositivos" },
{ "Çevre Koruma ve Geri Dönüşüm","Environmental Protection & Recycling","Protección Ambiental y Reciclaje","Umweltschutz & Recycling","Protection de l'Environnement & Recyclage","Proteção Ambiental e Reciclagem" },
{ "İleri Günlük İfadeler ve İş Hayatı","Advanced Daily Phrases & Work Life","Frases Avanzadas y Vida Laboral","Fortgeschrittene Alltagssätze & Arbeitsleben","Phrases Avançées & Vie Professionnelle","Frases Avançadas e Vida Profissional" }
};
private readonly string[] scoreLabel =
{
"Puan","Score","Puntuación","Punkte","Score","Pontuação"
};
// ============================================================
void Start()
{
string ansLang = PlayerPrefs.GetString("AnswerLangCode", "tr").ToLower();
langIndex = GetLangIndex(ansLang);
CacheButtonData();
SetupLevelNames();
LoadScoresToUI();
BindButtons();
// ─── Buton giriş animasyonu ───────────────
for (int i = 0; i < levelButtons.Length; i++)
StartCoroutine(ButtonEnterAnim(levelButtons[i], i));
}
// ============================================================
int GetLangIndex(string code)
{
return code switch
{
"tr" => 0,
"en" => 1,
"es" => 2,
"de" => 3,
"fr" => 4,
"pt" => 5,
_ => 1
};
}
// ============================================================
void CacheButtonData()
{
if (levelButtons == null) return;
originalScales = new Vector3[levelButtons.Length];
originalPositions = new Vector3[levelButtons.Length];
for (int i = 0; i < levelButtons.Length; i++)
{
if (levelButtons[i] == null) continue;
originalScales[i] = levelButtons[i].transform.localScale;
originalPositions[i] = levelButtons[i].transform.localPosition;
}
}
// ============================================================
void SetupLevelNames()
{
if (levelNameTexts == null) return;
for (int i = 0; i < levelNameTexts.Length; i++)
if (levelNameTexts[i] != null)
levelNameTexts[i].text = levelNames[i, langIndex];
}
// ============================================================
void BindButtons()
{
if (levelButtons == null) return;
for (int i = 0; i < levelButtons.Length; i++)
{
if (levelButtons[i] == null) continue;
int id = i + 1;
levelButtons[i].onClick.RemoveAllListeners();
levelButtons[i].onClick.AddListener(() =>
{
PlayClick();
PlayerPrefs.SetInt("SelectedLevel", id);
PlayerPrefs.Save();
SceneManager.LoadScene("LLGameScene_Level");
});
}
if (backButton != null)
backButton.onClick.AddListener(() => { PlayClick(); SceneManager.LoadScene(backSceneName); });
}
// ============================================================
void LoadScoresToUI()
{
if (levelScoreTexts == null) return;
for (int i = 0; i < levelScoreTexts.Length; i++)
{
if (levelScoreTexts[i] == null) continue;
int levelID = i + 1;
int highScore = PlayerPrefs.GetInt("HighScore_Level_" + levelID, 0);
if (highScore >= 2000)
{
levelScoreTexts[i].text = $"{scoreLabel[langIndex]}: 2000 / 2000";
levelScoreTexts[i].color = Color.green;
}
else
{
levelScoreTexts[i].text = $"{scoreLabel[langIndex]}: {highScore} / 2000";
levelScoreTexts[i].color = Color.red;
}
}
}
// ============================================================
void PlayClick()
{
if (sfxSource != null && clickSound != null)
sfxSource.PlayOneShot(clickSound);
}
// ============================================================
// ANİMASYONLAR
// ============================================================
IEnumerator ButtonEnterAnim(Button btn, int delayIndex)
{
if (btn == null || originalScales == null) yield break;
int idx = System.Array.IndexOf(levelButtons, btn);
if (idx < 0 || idx >= originalScales.Length) yield break;
yield return new WaitForSeconds(delayIndex * 0.08f);
Vector3 targetPos = originalPositions[idx];
Vector3 startPos = targetPos + Vector3.up * 60f;
Vector3 targetScale = originalScales[idx];
btn.transform.localPosition = startPos;
btn.transform.localScale = Vector3.zero;
float t = 0f;
while (t < 1f)
{
t = Mathf.Min(t + buttonAniSpeed * 0.13f, 1f);
float ease = EaseOutBack(t);
btn.transform.localPosition = Vector3.Lerp(startPos, targetPos, ease);
btn.transform.localScale = Vector3.Lerp(Vector3.zero, targetScale, ease);
yield return null;
}
btn.transform.localPosition = targetPos;
btn.transform.localScale = targetScale;
}
IEnumerator PunchScale(Button btn, int idx)
{
if (btn == null || originalScales == null) yield break;
if (idx < 0 || idx >= originalScales.Length) yield break;
Vector3 original = originalScales[idx];
Vector3 big = original * 1.08f;
float t = 0f;
while (t < 1f) { t = Mathf.Min(t + 0.15f, 1f); btn.transform.localScale = Vector3.Lerp(original, big, EaseOutQuad(t)); yield return null; }
t = 0f;
while (t < 1f) { t = Mathf.Min(t + 0.12f, 1f); btn.transform.localScale = Vector3.Lerp(big, original, EaseOutQuad(t)); yield return null; }
btn.transform.localScale = original;
}
// ============================================================
float EaseOutBack(float t)
{
float c1 = 1.70158f;
float c3 = c1 + 1f;
return 1f + c3 * Mathf.Pow(t - 1f, 3f) + c1 * Mathf.Pow(t - 1f, 2f);
}
float EaseOutQuad(float t) => 1f - (1f - t) * (1f - t);
}

View file

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 1bdc7981307c4924f9526f3bba47b417

View file

@ -0,0 +1,53 @@
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
public class ModeSelectController : MonoBehaviour
{
[SerializeField] private Button[] modButtons = new Button[30];
[SerializeField] private Button backButton;
[SerializeField] private string mainMenuScene = "Anamen";
[SerializeField] private AudioSource audioSource;
[SerializeField] private AudioClip clickSound;
[Header("MOD Sahneleri")]
[SerializeField] private string[] modScenes = new string[30];
void Start()
{
// Bind mod buttons
for (int i = 0; i < 30; i++)
{
if (modButtons[i] != null)
{
int modID = i + 1;
modButtons[i].onClick.AddListener(() => SelectMode(modID));
}
}
// Back button
if (backButton != null)
backButton.onClick.AddListener(() => LoadScene(mainMenuScene));
}
void SelectMode(int modID)
{
PlaySound();
PlayerPrefs.SetInt("SelectedMode", modID);
PlayerPrefs.Save();
string sceneName = modScenes[modID - 1];
LoadScene(sceneName);
}
void LoadScene(string sceneName)
{
SceneManager.LoadScene(sceneName);
}
void PlaySound()
{
if (audioSource && clickSound)
audioSource.PlayOneShot(clickSound);
}
}

View file

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: d46006198cd5c3b4d8c76badb7f20a2c

View file

@ -0,0 +1,101 @@
using UnityEngine;
using UnityEngine.UI;
using TMPro;
using UnityEngine.SceneManagement;
public class ResultScene_Galaxy : MonoBehaviour
{
[Header("RESULT TEXTS")]
public TMP_Text scoreText;
public TMP_Text correctText;
public TMP_Text wrongText;
public TMP_Text statusText;
[Header("BUTTONS")]
public Button retryButton;
public Button mainMenuButton;
[Header("SCENES (Inspector'dan gir)")]
public string retrySceneName = "GalaxyGameScene_Level"; // tekrar oyna -> oyun sahnesi
public string mainMenuScene = "Anamen";
[Header("SUCCESS THRESHOLD")]
public int successScoreThreshold = 2000;
[Header("AUDIO")]
public AudioSource audioSource;
public AudioClip clickSound;
private int score;
private int correct;
private int wrong;
void Start()
{
score = PlayerPrefs.GetInt("Mod3Score", 0);
correct = PlayerPrefs.GetInt("Mod3Correct", 0);
wrong = PlayerPrefs.GetInt("Mod3Wrong", 0);
if (scoreText != null) scoreText.text = score.ToString();
if (correctText != null) correctText.text = correct.ToString();
if (wrongText != null) wrongText.text = wrong.ToString();
if (statusText != null)
{
if (score >= successScoreThreshold)
{
statusText.text = "LEVEL PASSED";
statusText.color = Color.green;
}
else
{
statusText.text = "FAILED";
statusText.color = Color.red;
}
}
if (retryButton != null)
{
retryButton.onClick.RemoveAllListeners();
retryButton.onClick.AddListener(() =>
{
PlayClick();
LoadScene(retrySceneName);
});
}
if (mainMenuButton != null)
{
mainMenuButton.onClick.RemoveAllListeners();
mainMenuButton.onClick.AddListener(() =>
{
PlayClick();
LoadScene(mainMenuScene);
});
}
}
void LoadScene(string sceneName)
{
if (string.IsNullOrWhiteSpace(sceneName))
{
Debug.LogError("ResultScene: Sahne adı boş! Inspector'dan doldur.");
return;
}
if (!Application.CanStreamedLevelBeLoaded(sceneName))
{
Debug.LogError("ResultScene: '" + sceneName +
"' sahnesi Build Settings'te yok ya da adı yanlış!");
return;
}
SceneManager.LoadScene(sceneName);
}
void PlayClick()
{
if (audioSource && clickSound)
audioSource.PlayOneShot(clickSound);
}
}

View file

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 1ec4b2e43350ee04097c45d54640af8f

View file

@ -0,0 +1,221 @@
using UnityEngine;
using UnityEngine.UI;
using TMPro;
using UnityEngine.SceneManagement;
public class ResultScene_TTE : MonoBehaviour
{
[Header("UI Texts")]
public TMP_Text levelNameText;
public TMP_Text scoreText;
public TMP_Text highScoreText;
public TMP_Text correctText;
public TMP_Text wrongText;
public TMP_Text resultStatusText;
[Header("Buttons")]
public Button retryButton;
public Button levelMapButton;
public Button mainMenuButton;
[Header("Audio")]
public AudioSource audioSource;
public AudioClip clickSound;
[Header("Scene Names")]
[SerializeField] private string levelMapScene = "StageLevelMap";
[SerializeField] private string mainMenuScene = "Anamen";
[SerializeField] private string gameSceneName = "LLGameScene_Level";
private int score;
private int correct;
private int wrong;
private int selectedLevel;
private int langIndex; // CEVAP DİLİ İNDEKSİ
// ===========================
// 20 LEVEL ADI (6 DİL)
// ===========================
private readonly string[,] levelNames = new string[,]
{
{ "Temel Selamlaşma ve İnsanlar","Basic Greetings & People","Saludos Básicos y Personas","Grundbegrüßungen & Menschen","Salutations de Base & Personnes","Saudações Básicas e Pessoas" },
{ "Günlük Ev Nesneleri","Daily Household Items","Objetos del Hogar Diarios","Tägliche Haushaltsgegenstände","Objets Quotidiens de la Maison","Objetos Domésticos Diários" },
{ "Yiyecekler ve İçecekler","Food & Drinks","Comida y Bebida","Essen & Getränke","Nourriture & Boissons","Comidas e Bebidas" },
{ "Renkler, Şekiller ve Boyutlar","Colors, Shapes & Sizes","Colores, Formas y Tamaños","Farben, Formen & Größen","Couleurs, Formes & Tailles","Cores, Formas e Tamanhos" },
{ "Zaman, Günler ve Mevsimler","Time, Days & Seasons","Tiempo, Días y Estaciones","Zeit, Tage & Jahreszeiten","Temps, Jours & Saisons","Tempo, Dias e Estações" },
{ "Ev İçi Alanlar ve Temizlik","Home Areas & Cleaning","Áreas del Hogar y Limpieza","Hausbereiche & Reinigung","Espaces de Maison & Nettoyage","Áreas da Casa e Limpeza" },
{ "Okul, Eğitim ve Ders Araçları","School, Education & Supplies","Escuela, Educación y Útiles","Schule, Bildung & Materialien","École, Éducation & Fournitures","Escola, Educação e Materiais" },
{ "Vücut Parçaları ve Sağlık","Body Parts & Health","Partes del Cuerpo y Salud","Körperteile & Gesundheit","Parties du Corps & Santé","Partes do Corpo e Saúde" },
{ "Doğa, Hava ve Çevre Unsurları","Nature, Weather & Environment","Naturaleza, Clima y Medio Ambiente","Natur, Wetter & Umwelt","Nature, Météo & Environnement","Natureza, Clima e Meio Ambiente" },
{ "Evcil ve Vahşi Hayvanlar","Pets & Wild Animals","Mascotas y Animales Salvajes","Haustiere & Wildtiere","Animaux Domestiques & Sauvages","Animais Domésticos e Selvagens" },
{ "Ulaşım Araçları ve Trafik","Transportation & Traffic","Transporte y Tráfico","Transport & Verkehr","Transport & Circulation","Transporte e Trânsito" },
{ "Alışveriş ve Mağazalar","Shopping & Stores","Compras y Tiendas","Einkaufen & Geschäfte","Shopping & Magasins","Compras e Lojas" },
{ "Spor Dalları ve Ekipmanları","Sports & Equipment","Deportes y Equipamiento","Sportarten & Ausrüstung","Sports & Équipement","Esportes e Equipamentos" },
{ "Meslekler ve İş Alanları","Jobs & Work Fields","Profesiones y Áreas Laborales","Berufe & Arbeitsfelder","Métiers & Domaines de Travail","Profissões e Áreas de Trabalho" },
{ "Şehir, Yerler ve Binalar","City, Places & Buildings","Ciudad, Lugares y Edificios","Stadt, Orte & Gebäude","Ville, Lieux & Bâtiments","Cidade, Lugares e Edifícios" },
{ "Duygular, Durumlar ve Karakter","Emotions, States & Character","Emociones, Estados y Carácter","Gefühle, Zustände & Charakter","Émotions, États & Caractère","Emoções, Estados e Caráter" },
{ "Seyahat, Tatil ve Turizm","Travel, Vacation & Tourism","Viajes, Vacaciones y Turismo","Reisen, Urlaub & Tourismus","Voyage, Vacances & Tourisme","Viagem, Férias e Turismo" },
{ "Teknoloji, İnternet ve Cihazlar","Technology, Internet & Devices","Tecnología, Internet y Dispositivos","Technologie, Internet & Geräte","Technologie, Internet & Appareils","Tecnologia, Internet e Dispositivos" },
{ "Çevre Koruma ve Geri Dönüşüm","Environmental Protection & Recycling","Protección Ambiental y Reciclaje","Umweltschutz & Recycling","Protection de l'Environnement & Recyclage","Proteção Ambiental e Reciclagem" },
{ "İleri Günlük İfadeler ve İş Hayatı","Advanced Daily Phrases & Work Life","Frases Avanzadas y Vida Laboral","Fortgeschrittene Alltagssätze & Arbeitsleben","Phrases Avancées & Vie Professionnelle","Frases Avançadas e Vida Profissional" }
};
private readonly string[] labelScore = { " ", " ", " ", " ", " ", " " };
private readonly string[] labelHighScore = { " ", " ", " ", " ", " ", " " };
private readonly string[] labelCorrect = { " ", " ", " ", " ", " ", " " };
private readonly string[] labelWrong = { " ", " ", " ", " ", " ", " " };
private readonly string[] labelPassed = {
"TEBRİKLER! 🎉 LEVEL GEÇİLDİ",
"CONGRATULATIONS! 🎉 LEVEL CLEARED",
"¡FELICIDADES! 🎉 NIVEL COMPLETADO",
"GLÜCKWUNSCH! 🎉 LEVEL GESCHAFFT",
"FÉLICITATIONS ! 🎉 NIVEAU RÉUSSI",
"PARABÉNS! 🎉 NÍVEL CONCLUÍDO"
};
private readonly string[] labelFailed = {
"LEVEL BAŞARISIZ ❌",
"LEVEL FAILED ❌",
"NIVEL FALLIDO ❌",
"LEVEL NICHT BESTANDEN ❌",
"NIVEAU ÉCHOUÉ ❌",
"NÍVEL REPROVADO ❌"
};
// ============================================================
void Start()
{
// 1) Dil indexini al
string ansLang = PlayerPrefs.GetString("AnswerLangCode", "tr").ToLower();
langIndex = GetLangIndex(ansLang);
// 2) Sonuçları yükle + high score kaydet
LoadResults();
SaveHighScore();
// 3) ÖNCE butonları bağla (Start hata alsa bile en azından buraya kadar gelsin)
if (retryButton != null)
{
retryButton.onClick.RemoveAllListeners();
retryButton.onClick.AddListener(OnRetry);
}
if (levelMapButton != null)
{
levelMapButton.onClick.RemoveAllListeners();
levelMapButton.onClick.AddListener(OnLevelMap);
}
if (mainMenuButton != null)
{
mainMenuButton.onClick.RemoveAllListeners();
mainMenuButton.onClick.AddListener(OnMainMenu);
}
// 4) UIı güncelle (null-safe)
UpdateUI();
}
// ============================================================
int GetLangIndex(string code)
{
switch (code)
{
case "tr": return 0;
case "en": return 1;
case "es": return 2;
case "de": return 3;
case "fr": return 4;
case "pt": return 5;
}
return 1;
}
// ============================================================
void LoadResults()
{
score = PlayerPrefs.GetInt("Mod2Score", 0);
correct = PlayerPrefs.GetInt("Mod2Correct", 0);
wrong = PlayerPrefs.GetInt("Mod2Wrong", 0);
selectedLevel = Mathf.Clamp(PlayerPrefs.GetInt("SelectedLevel", 1), 1, 20);
}
// ============================================================
void SaveHighScore()
{
string key = "HighScore_Level_" + selectedLevel;
int old = PlayerPrefs.GetInt(key, 0);
if (score > old)
{
PlayerPrefs.SetInt(key, score);
PlayerPrefs.Save();
}
}
// ============================================================
void UpdateUI()
{
int safeLang = Mathf.Clamp(langIndex, 0, 5);
int idx = Mathf.Clamp(selectedLevel - 1, 0, 19);
if (levelNameText != null)
levelNameText.text = $"LEVEL {selectedLevel}\n{levelNames[idx, safeLang]}";
if (scoreText != null)
scoreText.text = $"{labelScore[safeLang]} {score}";
if (highScoreText != null)
highScoreText.text = $"{labelHighScore[safeLang]} {PlayerPrefs.GetInt("HighScore_Level_" + selectedLevel, 0)}";
if (correctText != null)
correctText.text = $"{labelCorrect[safeLang]} {correct}";
if (wrongText != null)
wrongText.text = $"{labelWrong[safeLang]} {wrong}";
if (resultStatusText != null)
{
if (score >= 2000)
{
resultStatusText.text = labelPassed[safeLang];
resultStatusText.color = Color.green;
}
else
{
resultStatusText.text = labelFailed[safeLang];
resultStatusText.color = Color.red;
}
}
}
// ============================================================
void OnRetry()
{
PlayClick();
if (!string.IsNullOrEmpty(gameSceneName))
SceneManager.LoadScene(gameSceneName);
}
void OnLevelMap()
{
PlayClick();
if (!string.IsNullOrEmpty(levelMapScene))
SceneManager.LoadScene(levelMapScene);
}
void OnMainMenu()
{
PlayClick();
if (!string.IsNullOrEmpty(mainMenuScene))
SceneManager.LoadScene(mainMenuScene);
}
void PlayClick()
{
if (audioSource && clickSound)
audioSource.PlayOneShot(clickSound);
}
}

View file

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: b574853e950b6cf48a084ac772956c65

8
Assets/Scripts/3.0.meta Normal file
View file

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 9360ad261eb62e643b8376ff33da5be4
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 361cc2564c58fe6449c1822064d12c32
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,804 @@
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
public class ClozeGameScene : MonoBehaviour
{
[Header("TXT DOSYASI (6 Dil)")]
public TextAsset questionFile;
[Header("UI")]
public TMP_Text questionText;
public TMP_Text[] answerTexts;
public Button[] answerButtons;
public Button submitButton;
public TMP_Text scoreText;
public TMP_Text comboText;
public TMP_Text timerText;
public TMP_Text feedbackText;
[Header("EXTRA BUTTONS")]
public Button extraTimeButton;
public Button extraHintButton;
public Button extraSkipButton;
[Header("━━━ BACK BUTTON ━━━━━━━━━━━━━━━━━━━━━━━━")]
public Button backButton;
public string backSceneName = "ModSec 4";
[Header("RENKLER")]
public Color normalColor = new Color32(255, 255, 255, 255);
public Color selectedColor = new Color32(60, 110, 200, 255);
public Color correctColor = new Color32(0, 200, 0, 255);
public Color wrongColor = new Color32(200, 0, 0, 255);
public Color hintColor = new Color32(255, 255, 128, 255);
[Header("━━━ FEEDBACK TEXT SETTINGS ━━━━━━━━━━━━━")]
public bool feedbackOnTop = true;
public float feedbackTopY = 400f;
public float feedbackFontSize = 72f;
[Header("━━━ ANIMATION SETTINGS ━━━━━━━━━━━━━━━━━")]
[Range(0.80f, 1f)] public float selectedScale = 0.94f;
public float selectAnimTime = 0.10f;
public float enterAnimTime = 0.22f;
// ---------------- INTERNAL STATE ----------------
private class ClozeEntry
{
public string[] q = new string[6];
public string[] c = new string[6];
public string[] w1 = new string[6];
public string[] w2 = new string[6];
public string[] w3 = new string[6];
}
private List<ClozeEntry> questions = new List<ClozeEntry>();
private int selected = -1;
private int correctIndex = -1;
private int lastQuestionID = -1;
private int score = 0;
private int combo = 0;
private int correctCount = 0;
private int wrongCount = 0;
private float timeLeft = 60f;
private float nextDelay = 1.2f;
private bool locked = false;
private string lang;
private string modKey = "Mod4"; // ✅ Bu modun özel key'i
readonly Color timerNormalColor = Color.white;
readonly Color timerWarnColor = new Color32(255, 80, 80, 255);
Vector3[] originalButtonScales;
Vector3[] originalButtonPositions;
Coroutine[] buttonScaleCoroutines;
Coroutine[] buttonEnterCoroutines;
// ------------------------------------------------
void Start()
{
lang = PlayerPrefs.GetString("QuestionLangCode", "en");
if (questionFile == null)
{
Debug.LogError("TXT Dosyası atanmadı!");
return;
}
LoadTXT(questionFile.text);
CacheButtonData();
ForceButtonTransitionNone();
PrepareFeedbackText();
submitButton.onClick.AddListener(OnSubmit);
extraTimeButton.onClick.AddListener(() => { if (!locked) timeLeft += 5; });
extraHintButton.onClick.AddListener(OnHint);
extraSkipButton.onClick.AddListener(() => NextQuestion());
if (backButton != null)
{
backButton.onClick.RemoveAllListeners();
backButton.onClick.AddListener(() => SceneManager.LoadScene(backSceneName));
}
scoreText.text = "0";
comboText.text = "0x";
feedbackText.text = "";
NextQuestion();
}
// ------------------------------------------------
void Update()
{
if (!locked)
{
timeLeft -= Time.deltaTime;
if (timeLeft <= 0)
{
timeLeft = 0;
GameOver();
}
}
UpdateTimerUI();
}
// ------------------------------------------------
void CacheButtonData()
{
if (answerButtons == null) return;
int len = answerButtons.Length;
originalButtonScales = new Vector3[len];
originalButtonPositions = new Vector3[len];
buttonScaleCoroutines = new Coroutine[len];
buttonEnterCoroutines = new Coroutine[len];
for (int i = 0; i < len; i++)
{
if (answerButtons[i] == null) continue;
originalButtonScales[i] = answerButtons[i].transform.localScale;
originalButtonPositions[i] = answerButtons[i].transform.localPosition;
}
}
void ForceButtonTransitionNone()
{
if (answerButtons == null) return;
for (int i = 0; i < answerButtons.Length; i++)
{
if (answerButtons[i] == null) continue;
answerButtons[i].transition = Selectable.Transition.None;
Image img = answerButtons[i].image;
if (img != null)
img.color = FullAlpha(normalColor);
}
}
void PrepareFeedbackText()
{
if (feedbackText == null) return;
if (feedbackOnTop)
{
Vector3 pos = feedbackText.transform.localPosition;
pos.y = feedbackTopY;
feedbackText.transform.localPosition = pos;
}
feedbackText.alignment = TextAlignmentOptions.Center;
feedbackText.fontSize = Mathf.Max(feedbackText.fontSize, feedbackFontSize);
feedbackText.text = "";
Color c = feedbackText.color;
c.a = 1f;
feedbackText.color = c;
}
// ------------------------------------------------
void LoadTXT(string raw)
{
foreach (string line in raw.Trim().Split('\n'))
{
if (string.IsNullOrWhiteSpace(line)) continue;
string[] p = line.Split('|');
if (p.Length < 30)
{
Debug.LogWarning("Eksik satır: " + line);
continue;
}
ClozeEntry e = new ClozeEntry();
for (int i = 0; i < 6; i++)
{
e.q[i] = p[i].Trim();
e.c[i] = p[6 + i].Trim();
e.w1[i] = p[12 + i].Trim();
e.w2[i] = p[18 + i].Trim();
e.w3[i] = p[24 + i].Trim();
}
questions.Add(e);
}
}
// ------------------------------------------------
void NextQuestion()
{
locked = false;
feedbackText.text = "";
selected = -1;
ResetButtons();
// Aynı soru ard arda gelmesin
int id = Random.Range(0, questions.Count);
if (id == lastQuestionID && questions.Count > 1)
id = (id + 1) % questions.Count;
lastQuestionID = id;
ClozeEntry q = questions[id];
int L = GetLangIndex();
questionText.text = q.q[L];
StartCoroutine(FadeInText(questionText));
List<string> opts = new List<string>()
{
q.c[L], q.w1[L], q.w2[L], q.w3[L]
};
Shuffle(opts);
// Şık yerleşimi
correctIndex = opts.IndexOf(q.c[L]);
for (int i = 0; i < 4; i++)
{
answerTexts[i].text = opts[i];
int index = i;
answerButtons[i].onClick.RemoveAllListeners();
answerButtons[i].onClick.AddListener(() => SelectAnswer(index));
}
for (int i = 0; i < answerButtons.Length; i++)
{
if (answerButtons[i] == null) continue;
if (buttonEnterCoroutines[i] != null)
StopCoroutine(buttonEnterCoroutines[i]);
buttonEnterCoroutines[i] = StartCoroutine(ButtonEnterAnim(answerButtons[i], i));
}
}
// ------------------------------------------------
void ResetButtons()
{
if (answerButtons == null) return;
for (int i = 0; i < answerButtons.Length; i++)
{
if (answerButtons[i] == null) continue;
StopButtonCoroutines(i);
answerButtons[i].interactable = true;
answerButtons[i].transition = Selectable.Transition.None;
Image img = answerButtons[i].image;
if (img != null)
img.color = FullAlpha(normalColor);
answerButtons[i].transform.localScale = originalButtonScales[i];
answerButtons[i].transform.localPosition = originalButtonPositions[i];
}
}
// ------------------------------------------------
void SelectAnswer(int id)
{
if (locked) return;
if (selected == id)
return;
if (selected >= 0 && selected < answerButtons.Length)
{
Button oldButton = answerButtons[selected];
if (oldButton != null)
{
Image oldImg = oldButton.image;
if (oldImg != null)
oldImg.color = FullAlpha(normalColor);
StartScaleAnim(selected, originalButtonScales[selected]);
}
}
selected = id;
Image img = answerButtons[id].image;
if (img != null)
img.color = FullAlpha(selectedColor);
StartScaleAnim(id, originalButtonScales[id] * selectedScale);
}
// ------------------------------------------------
void OnSubmit()
{
if (selected == -1 || locked) return;
locked = true;
foreach (Button b in answerButtons)
b.interactable = false;
bool ok = (selected == correctIndex);
if (ok)
{
correctCount++;
combo++;
score += 50 + combo * 10;
Image img = answerButtons[selected].image;
if (img != null)
img.color = FullAlpha(correctColor);
StartCoroutine(CorrectPulse(answerButtons[selected], selected));
feedbackText.color = FullAlpha(correctColor);
feedbackText.text = combo >= 3 ? $"TRUE {combo}x COMBO!" : "TRUE";
timeLeft += 2f;
if (comboText != null) StartCoroutine(ComboAnim(comboText));
if (scoreText != null) StartCoroutine(ScorePopAnim(scoreText));
}
else
{
wrongCount++;
combo = 0;
Image selImg = answerButtons[selected].image;
if (selImg != null)
selImg.color = FullAlpha(wrongColor);
StartCoroutine(ShakeButton(answerButtons[selected], selected));
Image corImg = answerButtons[correctIndex].image;
if (corImg != null)
corImg.color = FullAlpha(correctColor);
StartScaleAnim(correctIndex, originalButtonScales[correctIndex] * 1.04f);
feedbackText.color = FullAlpha(wrongColor);
feedbackText.text = "FALSE";
}
scoreText.text = score.ToString();
comboText.text = combo + "x";
if (feedbackOnTop)
{
Vector3 pos = feedbackText.transform.localPosition;
pos.y = feedbackTopY;
feedbackText.transform.localPosition = pos;
}
StartCoroutine(FeedbackAnim(feedbackText));
StartCoroutine(NextDelay());
}
IEnumerator NextDelay()
{
yield return new WaitForSeconds(nextDelay);
NextQuestion();
}
// ------------------------------------------------
void OnHint()
{
if (locked) return;
Image img = answerButtons[correctIndex].image;
if (img != null)
img.color = FullAlpha(hintColor);
StartCoroutine(CorrectPulse(answerButtons[correctIndex], correctIndex));
feedbackText.color = FullAlpha(selectedColor);
feedbackText.text = "Hint: Correct Answer Highlighted!";
if (feedbackOnTop)
{
Vector3 pos = feedbackText.transform.localPosition;
pos.y = feedbackTopY;
feedbackText.transform.localPosition = pos;
}
StartCoroutine(FeedbackAnim(feedbackText));
}
// ------------------------------------------------
void GameOver()
{
PlayerPrefs.SetString("LastPlayedMod", modKey);
// 🔥 Mod Select / Leaderboard ekranına direkt bağlanacak basit key
PlayerPrefs.SetInt("Mod4Skor", score);
// Bu oyundaki sonuçlar
PlayerPrefs.SetInt(modKey + "_LastScore", score);
PlayerPrefs.SetInt(modKey + "_Correct", correctCount);
PlayerPrefs.SetInt(modKey + "_Wrong", wrongCount);
PlayerPrefs.SetInt(modKey + "_LastCombo", combo);
// 🔥 En iyi skor (Mod Select / Leaderboard için)
int oldMax = PlayerPrefs.GetInt(modKey + "_MaxScore", 0);
if (score > oldMax)
PlayerPrefs.SetInt(modKey + "_MaxScore", score);
// 🔥 En iyi combo
int oldBestCombo = PlayerPrefs.GetInt(modKey + "_BestCombo", 0);
if (combo > oldBestCombo)
PlayerPrefs.SetInt(modKey + "_BestCombo", combo);
// 🔥 Doğruluk oranı (%)
int totalAnswers = correctCount + wrongCount;
int accuracy = totalAnswers > 0 ? Mathf.RoundToInt((correctCount / (float)totalAnswers) * 100f) : 0;
PlayerPrefs.SetInt(modKey + "_LastAccuracy", accuracy);
// 🔥 Toplam istatistikler
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);
// 🔥 Genel toplam skor (Mod Select ekranındaki global leaderboard için)
PlayerPrefs.SetInt("TotalScore", PlayerPrefs.GetInt("TotalScore", 0) + score);
PlayerPrefs.Save();
SceneManager.LoadScene("Mod4Resume");
}
// ------------------------------------------------
int GetLangIndex()
{
return lang switch
{
"tr" => 0,
"en" => 1,
"es" => 2,
"de" => 3,
"fr" => 4,
"pt" => 5,
_ => 1
};
}
// ------------------------------------------------
void Shuffle<T>(IList<T> arr)
{
for (int i = 0; i < arr.Count; i++)
{
int r = Random.Range(i, arr.Count);
(arr[i], arr[r]) = (arr[r], arr[i]);
}
}
// ================== ANIMATION HELPERS ==================
void UpdateTimerUI()
{
if (timerText == null) return;
timerText.text = Mathf.Ceil(timeLeft).ToString();
if (timeLeft <= 10f)
{
timerText.color = FullAlpha(Color.Lerp(timerWarnColor, Color.white, Mathf.PingPong(Time.time * 3f, 1f)));
timerText.transform.localScale = Vector3.one * (1f + Mathf.Sin(Time.time * 10f) * 0.05f);
}
else
{
timerText.color = FullAlpha(timerNormalColor);
timerText.transform.localScale = Vector3.one;
}
}
void StartScaleAnim(int index, Vector3 targetScale)
{
if (index < 0 || index >= answerButtons.Length) return;
if (answerButtons[index] == null) return;
if (buttonScaleCoroutines[index] != null)
StopCoroutine(buttonScaleCoroutines[index]);
buttonScaleCoroutines[index] = StartCoroutine(ScaleButton(answerButtons[index], targetScale));
}
void StopButtonCoroutines(int index)
{
if (buttonScaleCoroutines != null && index < buttonScaleCoroutines.Length && buttonScaleCoroutines[index] != null)
{
StopCoroutine(buttonScaleCoroutines[index]);
buttonScaleCoroutines[index] = null;
}
if (buttonEnterCoroutines != null && index < buttonEnterCoroutines.Length && buttonEnterCoroutines[index] != null)
{
StopCoroutine(buttonEnterCoroutines[index]);
buttonEnterCoroutines[index] = null;
}
}
IEnumerator ScaleButton(Button btn, Vector3 targetScale)
{
if (btn == null) yield break;
Vector3 startScale = btn.transform.localScale;
float t = 0f;
while (t < 1f)
{
t += Time.deltaTime / Mathf.Max(0.01f, selectAnimTime);
btn.transform.localScale = Vector3.Lerp(startScale, targetScale, EaseOutQuad(t));
yield return null;
}
btn.transform.localScale = targetScale;
}
IEnumerator ButtonEnterAnim(Button btn, int delayIndex)
{
if (btn == null) yield break;
int idx = System.Array.IndexOf(answerButtons, btn);
if (idx < 0) yield break;
yield return new WaitForSeconds(delayIndex * 0.06f);
Vector3 targetPos = originalButtonPositions[idx];
Vector3 startPos = targetPos + Vector3.up * 35f;
Vector3 targetScale = originalButtonScales[idx];
Vector3 startScale = targetScale * 0.85f;
btn.transform.localPosition = startPos;
btn.transform.localScale = startScale;
float t = 0f;
while (t < 1f)
{
t += Time.deltaTime / Mathf.Max(0.01f, enterAnimTime);
float ease = EaseOutBack(t);
btn.transform.localPosition = Vector3.Lerp(startPos, targetPos, ease);
btn.transform.localScale = Vector3.Lerp(startScale, targetScale, ease);
yield return null;
}
btn.transform.localPosition = targetPos;
btn.transform.localScale = targetScale;
}
IEnumerator CorrectPulse(Button btn, int idx)
{
if (btn == null) yield break;
Vector3 normal = originalButtonScales[idx];
Vector3 big = normal * 1.12f;
float t = 0f;
while (t < 1f)
{
t += Time.deltaTime / 0.12f;
btn.transform.localScale = Vector3.Lerp(normal, big, EaseOutQuad(t));
yield return null;
}
t = 0f;
while (t < 1f)
{
t += Time.deltaTime / 0.12f;
btn.transform.localScale = Vector3.Lerp(big, normal, EaseOutQuad(t));
yield return null;
}
btn.transform.localScale = normal;
}
IEnumerator ShakeButton(Button btn, int idx)
{
if (btn == null) yield break;
Vector3 origin = originalButtonPositions[idx];
float duration = 0.35f;
float magnitude = 12f;
float elapsed = 0f;
while (elapsed < duration)
{
float power = 1f - elapsed / duration;
float x = Random.Range(-1f, 1f) * magnitude * power;
btn.transform.localPosition = origin + new Vector3(x, 0f, 0f);
elapsed += Time.deltaTime;
yield return null;
}
btn.transform.localPosition = origin;
}
IEnumerator FeedbackAnim(TMP_Text txt)
{
if (txt == null) yield break;
Vector3 originalScale = txt.transform.localScale;
Vector3 bigScale = originalScale * 1.18f;
Color c = FullAlpha(txt.color);
c.a = 0f;
txt.color = c;
Vector3 originalPos = txt.transform.localPosition;
Vector3 startPos = originalPos + Vector3.down * 18f;
txt.transform.localPosition = startPos;
float t = 0f;
while (t < 1f)
{
t += Time.deltaTime / 0.16f;
float ease = EaseOutBack(t);
txt.transform.localScale = Vector3.Lerp(originalScale, bigScale, ease);
txt.transform.localPosition = Vector3.Lerp(startPos, originalPos, ease);
c.a = Mathf.Clamp01(t);
txt.color = c;
yield return null;
}
c.a = 1f;
txt.color = c;
txt.transform.localPosition = originalPos;
t = 0f;
while (t < 1f)
{
t += Time.deltaTime / 0.12f;
txt.transform.localScale = Vector3.Lerp(bigScale, originalScale, EaseOutQuad(t));
yield return null;
}
txt.transform.localScale = originalScale;
}
IEnumerator ComboAnim(TMP_Text txt)
{
if (txt == null) yield break;
Vector3 original = txt.transform.localScale;
Vector3 big = original * 1.22f;
Color baseColor = FullAlpha(txt.color);
Color highlight = new Color32(255, 220, 50, 255);
float t = 0f;
while (t < 1f)
{
t += Time.deltaTime / 0.12f;
txt.transform.localScale = Vector3.Lerp(original, big, EaseOutBack(t));
txt.color = FullAlpha(Color.Lerp(baseColor, highlight, t));
yield return null;
}
t = 0f;
while (t < 1f)
{
t += Time.deltaTime / 0.14f;
txt.transform.localScale = Vector3.Lerp(big, original, EaseOutQuad(t));
txt.color = FullAlpha(Color.Lerp(highlight, baseColor, t));
yield return null;
}
txt.transform.localScale = original;
txt.color = baseColor;
}
IEnumerator ScorePopAnim(TMP_Text txt)
{
if (txt == null) yield break;
Vector3 original = txt.transform.localScale;
Vector3 big = original * 1.18f;
float t = 0f;
while (t < 1f)
{
t += Time.deltaTime / 0.10f;
txt.transform.localScale = Vector3.Lerp(original, big, EaseOutQuad(t));
yield return null;
}
t = 0f;
while (t < 1f)
{
t += Time.deltaTime / 0.12f;
txt.transform.localScale = Vector3.Lerp(big, original, EaseOutQuad(t));
yield return null;
}
txt.transform.localScale = original;
}
IEnumerator FadeInText(TMP_Text txt)
{
if (txt == null) yield break;
Color c = FullAlpha(txt.color);
c.a = 0f;
txt.color = c;
float t = 0f;
while (t < 1f)
{
t += Time.deltaTime / 0.18f;
c.a = EaseOutQuad(t);
txt.color = c;
yield return null;
}
c.a = 1f;
txt.color = c;
}
Color FullAlpha(Color c)
{
c.a = 1f;
return c;
}
float EaseOutBack(float t)
{
t = Mathf.Clamp01(t);
float c1 = 1.70158f;
float c3 = c1 + 1f;
return 1f + c3 * Mathf.Pow(t - 1f, 3f) + c1 * Mathf.Pow(t - 1f, 2f);
}
float EaseOutQuad(float t)
{
t = Mathf.Clamp01(t);
return 1f - (1f - t) * (1f - t);
}
}

View file

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: e2fc2555785ff244ca431198dfe8bc21

View file

@ -0,0 +1,168 @@
using System.Collections;
using TMPro;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
public class Mod4Resume : MonoBehaviour
{
[Header("UI TEXTS (ONLY NUMBERS)")]
public TMP_Text scoreText;
public TMP_Text maxScoreText;
public TMP_Text correctText;
public TMP_Text wrongText;
[Header("BUTTONS")]
public Button retryButton;
public Button exitButton;
[Header("AUDIO")]
public AudioSource sfx;
public AudioClip clickSound;
[Header("━━━ ANIMATION SETTINGS ━━━━━━━━━━━━━━━━━")]
public float countUpDuration = 0.8f;
public float popInDelay = 0.08f;
public float popInTime = 0.3f;
// Bu modun kendi ana anahtarı
private string modKey = "Mod4";
private int score;
private int maxScore;
private int correct;
private int wrong;
void Start()
{
LoadResults();
PrepareTexts();
if (retryButton != null)
retryButton.onClick.AddListener(() => { PlaySFX(); Retry(); });
if (exitButton != null)
exitButton.onClick.AddListener(() => { PlaySFX(); ExitToMenu(); });
StartCoroutine(PlayRevealSequence());
}
// ---------------------------------------------------------------
void LoadResults()
{
score = PlayerPrefs.GetInt(modKey + "_LastScore", 0);
maxScore = PlayerPrefs.GetInt(modKey + "_MaxScore", 0);
correct = PlayerPrefs.GetInt(modKey + "_Correct", 0);
wrong = PlayerPrefs.GetInt(modKey + "_Wrong", 0);
Debug.Log("MOD4 RESULT → " +
$"Score:{score} | Max:{maxScore} | C:{correct} | W:{wrong}");
}
// ---------------------------------------------------------------
void PrepareTexts()
{
SetTextZero(scoreText);
SetTextZero(maxScoreText);
SetTextZero(correctText);
SetTextZero(wrongText);
}
void SetTextZero(TMP_Text txt)
{
if (txt == null) return;
txt.text = "0";
txt.transform.localScale = Vector3.zero;
}
// ---------------------------------------------------------------
IEnumerator PlayRevealSequence()
{
yield return StartCoroutine(RevealStat(scoreText, score));
yield return new WaitForSeconds(popInDelay);
yield return StartCoroutine(RevealStat(maxScoreText, maxScore));
yield return new WaitForSeconds(popInDelay);
yield return StartCoroutine(RevealStat(correctText, correct));
yield return new WaitForSeconds(popInDelay);
yield return StartCoroutine(RevealStat(wrongText, wrong));
}
IEnumerator RevealStat(TMP_Text txt, int targetValue)
{
if (txt == null) yield break;
// pop-in scale
Vector3 normal = Vector3.one;
float t = 0f;
while (t < 1f)
{
t += Time.deltaTime / Mathf.Max(0.01f, popInTime);
txt.transform.localScale = Vector3.Lerp(Vector3.zero, normal, EaseOutBack(t));
if (targetValue == 0)
txt.text = "0";
yield return null;
}
txt.transform.localScale = normal;
// count-up
if (targetValue > 0)
{
float ct = 0f;
while (ct < 1f)
{
ct += Time.deltaTime / Mathf.Max(0.01f, countUpDuration);
int shown = Mathf.RoundToInt(Mathf.Lerp(0, targetValue, EaseOutQuad(ct)));
txt.text = shown.ToString();
yield return null;
}
}
txt.text = targetValue.ToString();
}
// ---------------------------------------------------------------
void PlaySFX()
{
if (sfx && clickSound)
sfx.PlayOneShot(clickSound);
}
// ---------------------------------------------------------------
void Retry()
{
// 🔥 MOD 4 OYUN SAHNESİNE GERİ DÖNÜŞ
SceneManager.LoadScene("Mod4");
}
// ---------------------------------------------------------------
void ExitToMenu()
{
SceneManager.LoadScene("Anamen");
}
// ---------------------------------------------------------------
float EaseOutBack(float t)
{
t = Mathf.Clamp01(t);
float c1 = 1.70158f;
float c3 = c1 + 1f;
return 1f + c3 * Mathf.Pow(t - 1f, 3f) + c1 * Mathf.Pow(t - 1f, 2f);
}
float EaseOutQuad(float t)
{
t = Mathf.Clamp01(t);
return 1f - (1f - t) * (1f - t);
}
}

View file

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 323d69d6258982b41ad0ec9e34e0ba98

View file

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 2b5728892019a2347bac5fea0b29df9a
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,90 @@
using TMPro;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
public class Mod5Resume : MonoBehaviour
{
[Header("UI TEXTS (ONLY NUMBERS)")]
public TMP_Text scoreText;
public TMP_Text maxScoreText;
public TMP_Text correctText;
public TMP_Text wrongText;
[Header("BUTTONS")]
public Button retryButton;
public Button exitButton;
[Header("AUDIO")]
public AudioSource sfx;
public AudioClip clickSound;
// 🔥 Bu modun özel ana keyi
private string modKey = "Mod5";
private int score;
private int maxScore;
private int correct;
private int wrong;
void Start()
{
LoadResults();
UpdateUI();
if (retryButton != null)
retryButton.onClick.AddListener(() =>
{
PlaySFX();
Retry();
});
if (exitButton != null)
exitButton.onClick.AddListener(() =>
{
PlaySFX();
ExitToMenu();
});
}
// ---------------------------------------------------------------
void LoadResults()
{
score = PlayerPrefs.GetInt(modKey + "_LastScore", 0);
maxScore = PlayerPrefs.GetInt(modKey + "_MaxScore", 0);
correct = PlayerPrefs.GetInt(modKey + "_Correct", 0);
wrong = PlayerPrefs.GetInt(modKey + "_Wrong", 0);
Debug.Log("MOD5 RESULT → " +
$"Score:{score} | Max:{maxScore} | C:{correct} | W:{wrong}");
}
// ---------------------------------------------------------------
void UpdateUI()
{
if (scoreText != null) scoreText.text = score.ToString();
if (maxScoreText != null) maxScoreText.text = maxScore.ToString();
if (correctText != null) correctText.text = correct.ToString();
if (wrongText != null) wrongText.text = wrong.ToString();
}
// ---------------------------------------------------------------
void PlaySFX()
{
if (sfx && clickSound)
sfx.PlayOneShot(clickSound);
}
// ---------------------------------------------------------------
void Retry()
{
// 🔥 Mod 5'in oyun sahnesine geri dönüş
SceneManager.LoadScene("Mod5");
}
// ---------------------------------------------------------------
void ExitToMenu()
{
SceneManager.LoadScene("Anamen");
}
}

View file

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 5aef591567d26be469298582b4dde11b

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: a63c8afea6ac9ef49808e75ed89dc7cb

View file

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 8bddf192a36777c4f89d9bc2f7c58312
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,177 @@
using System.Collections;
using TMPro;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
public class Mod6Resume : MonoBehaviour
{
[Header("UI TEXTS")]
public TMP_Text scoreText; // Toplam skor
public TMP_Text maxScoreText; // En yüksek skor
public TMP_Text correctText; // Doğru sayısı
public TMP_Text wrongText; // Yanlış sayısı
[Header("BUTTONS")]
public Button retryButton;
public Button exitButton;
[Header("AUDIO")]
public AudioSource sfx;
public AudioClip clickSound;
[Header("━━━ ANIMATION SETTINGS ━━━━━━━━━━━━━━━━━")]
public float countUpDuration = 0.8f;
public float popInDelay = 0.08f;
public float popInTime = 0.3f;
// Mod6 PlayerPrefs Key
private string modKey = "Mod6";
private int score;
private int maxScore;
private int correct;
private int wrong;
// ============================================================
void Start()
{
LoadResults();
PrepareTexts();
// Retry
if (retryButton != null)
retryButton.onClick.AddListener(() =>
{
PlaySFX();
Retry();
});
// Exit
if (exitButton != null)
exitButton.onClick.AddListener(() =>
{
PlaySFX();
ExitToMenu();
});
StartCoroutine(PlayRevealSequence());
}
// ============================================================
void LoadResults()
{
score = PlayerPrefs.GetInt(modKey + "_LastScore", 0);
maxScore = PlayerPrefs.GetInt(modKey + "_MaxScore", 0);
correct = PlayerPrefs.GetInt(modKey + "_Correct", 0);
wrong = PlayerPrefs.GetInt(modKey + "_Wrong", 0);
Debug.Log($"[MOD6 RESULT] Score={score} | Max={maxScore} | Correct={correct} | Wrong={wrong}");
}
// ============================================================
void PrepareTexts()
{
SetTextZero(scoreText);
SetTextZero(maxScoreText);
SetTextZero(correctText);
SetTextZero(wrongText);
}
void SetTextZero(TMP_Text txt)
{
if (txt == null) return;
txt.text = "0";
txt.transform.localScale = Vector3.zero;
}
// ============================================================
IEnumerator PlayRevealSequence()
{
yield return StartCoroutine(RevealStat(scoreText, score));
yield return new WaitForSeconds(popInDelay);
yield return StartCoroutine(RevealStat(maxScoreText, maxScore));
yield return new WaitForSeconds(popInDelay);
yield return StartCoroutine(RevealStat(correctText, correct));
yield return new WaitForSeconds(popInDelay);
yield return StartCoroutine(RevealStat(wrongText, wrong));
}
IEnumerator RevealStat(TMP_Text txt, int targetValue)
{
if (txt == null) yield break;
// pop-in scale
Vector3 normal = Vector3.one;
float t = 0f;
while (t < 1f)
{
t += Time.deltaTime / Mathf.Max(0.01f, popInTime);
txt.transform.localScale = Vector3.Lerp(Vector3.zero, normal, EaseOutBack(t));
if (targetValue == 0)
txt.text = "0";
yield return null;
}
txt.transform.localScale = normal;
// count-up
if (targetValue > 0)
{
float ct = 0f;
while (ct < 1f)
{
ct += Time.deltaTime / Mathf.Max(0.01f, countUpDuration);
int shown = Mathf.RoundToInt(Mathf.Lerp(0, targetValue, EaseOutQuad(ct)));
txt.text = shown.ToString();
yield return null;
}
}
txt.text = targetValue.ToString();
}
// ============================================================
void PlaySFX()
{
if (sfx && clickSound)
sfx.PlayOneShot(clickSound);
}
// ============================================================
void Retry()
{
SceneManager.LoadScene("Mod6");
}
// ============================================================
void ExitToMenu()
{
SceneManager.LoadScene("Anamen");
}
// ============================================================
float EaseOutBack(float t)
{
t = Mathf.Clamp01(t);
float c1 = 1.70158f;
float c3 = c1 + 1f;
return 1f + c3 * Mathf.Pow(t - 1f, 3f) + c1 * Mathf.Pow(t - 1f, 2f);
}
float EaseOutQuad(float t)
{
t = Mathf.Clamp01(t);
return 1f - (1f - t) * (1f - t);
}
}

View file

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 7732f4a1c046d054cadae9b2b5482c31

View file

@ -0,0 +1,897 @@
using UnityEngine;
using UnityEngine.UI;
using TMPro;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine.SceneManagement;
public class WordMatchMod : MonoBehaviour
{
[Header("UI - QUESTIONS (LEFT)")]
[SerializeField] private Button[] questionButtons;
[SerializeField] private TMP_Text[] questionTexts;
[Header("UI - ANSWERS (RIGHT)")]
[SerializeField] private Button[] answerButtons;
[SerializeField] private TMP_Text[] answerTexts;
[Header("UI - OTHER")]
[SerializeField] private Button submitButton;
[SerializeField] private TMP_Text scoreText;
[SerializeField] private TMP_Text comboText;
[SerializeField] private TMP_Text timeText;
[SerializeField] private TMP_Text feedbackText;
[Header("━━━ BACK BUTTON ━━━━━━━━━━━━━━━━━━━━━━━━")]
public Button backButton;
public string backSceneName = "ModSec 6";
[Header("WORD DATA")]
[SerializeField] private TextAsset wordFile;
[Header("COLORS")]
public Color baseColor = new Color32(230, 230, 230, 255);
public Color[] pairColors = new Color[]
{
new Color32(120,180,255,255),
new Color32(255,200,120,255),
new Color32(160,255,160,255),
new Color32(255,150,150,255),
new Color32(210,150,255,255),
};
public Color correctColor = new Color32(0, 160, 0, 255);
public Color wrongColor = new Color32(200, 0, 0, 255);
[Header("━━━ FEEDBACK TEXT SETTINGS ━━━━━━━━━━━━━")]
public bool feedbackOnTop = true;
public float feedbackTopY = 400f;
public float feedbackFontSize = 72f;
[Header("━━━ ANIMATION SETTINGS ━━━━━━━━━━━━━━━━━")]
[Range(0.80f, 1f)] public float selectedScale = 0.94f;
public float selectAnimTime = 0.10f;
public float enterAnimTime = 0.22f;
Dictionary<string, string> activeMap = new Dictionary<string, string>();
List<KeyValuePair<string, string>> selectedPairs = new List<KeyValuePair<string, string>>();
private int[] questionToAnswer = new int[5];
private int[] questionColorIdx = new int[5];
private int[] answerColorIdx = new int[5];
private int selectedQuestion = -1;
// 🔥 90 saniyelik toplam süre, round başına sıfırlanmıyor
private float timeLeft = 90f;
private int score = 0;
private int combo = 0;
private int correctCount = 0;
private int wrongCount = 0;
// Durum kontrolü
private bool isTimeUp = false; // süre tamamen bitti mi?
private bool isRoundProcessing = false; // bu round için submit işlemi devam ediyor mu?
// PlayerPrefs Key
private string modKey = "Mod6";
private string qLang;
private string aLang;
readonly Color timerNormalColor = Color.white;
readonly Color timerWarnColor = new Color32(255, 80, 80, 255);
Vector3[] questionOriginalScales;
Vector3[] answerOriginalScales;
Vector3[] questionOriginalPositions;
Vector3[] answerOriginalPositions;
Coroutine[] questionScaleCo;
Coroutine[] answerScaleCo;
Coroutine[] questionEnterCo;
Coroutine[] answerEnterCo;
Coroutine feedbackCo;
//---------------------------------------------------------
void Start()
{
qLang = PlayerPrefs.GetString("QuestionLangCode", "en");
aLang = PlayerPrefs.GetString("AnswerLangCode", "tr");
LoadWordFile();
CacheButtonData();
PrepareFeedbackText();
if (submitButton != null)
{
submitButton.onClick.RemoveAllListeners();
submitButton.onClick.AddListener(OnSubmit);
}
if (backButton != null)
{
backButton.onClick.RemoveAllListeners();
backButton.onClick.AddListener(() => SceneManager.LoadScene(backSceneName));
}
LoadRound();
ResetColorMaps();
// Oyun başlangıcı süresi
timeLeft = 90f;
isTimeUp = false;
isRoundProcessing = false;
scoreText.text = score.ToString();
comboText.text = combo + "x";
}
//---------------------------------------------------------
void Update()
{
if (isTimeUp) // süre bittiyse artık hiçbir şey yapma
{
UpdateTimerUI();
return;
}
timeLeft -= Time.deltaTime;
if (timeLeft < 0f) timeLeft = 0f;
UpdateTimerUI();
if (!isTimeUp && timeLeft <= 0f)
{
// Süre ilk kez bitti
isTimeUp = true;
ProcessSubmit(true); // timeout'tan gelen submit
StartCoroutine(GoResume()); // sonuç sahnesine git
}
}
//---------------------------------------------------------
void UpdateTimerUI()
{
if (timeText == null) return;
timeText.text = Mathf.CeilToInt(timeLeft).ToString();
if (timeLeft <= 10f)
{
timeText.color = FullAlpha(Color.Lerp(timerWarnColor, Color.white, Mathf.PingPong(Time.time * 3f, 1f)));
timeText.transform.localScale = Vector3.one * (1f + Mathf.Sin(Time.time * 10f) * 0.05f);
}
else
{
timeText.color = FullAlpha(timerNormalColor);
timeText.transform.localScale = Vector3.one;
}
}
//---------------------------------------------------------
void LoadWordFile()
{
activeMap.Clear();
string[] lines = wordFile.text.Split('\n');
int qi = LangIndex(qLang);
int ai = LangIndex(aLang);
foreach (string raw in lines)
{
string line = raw.Trim();
if (string.IsNullOrWhiteSpace(line)) continue;
if (!line.Contains(",")) continue;
string[] p = line.Split(',');
if (p.Length < 6) continue;
string q = p[qi].Trim();
string a = p[ai].Trim();
if (!activeMap.ContainsKey(q))
activeMap.Add(q, a);
}
}
int LangIndex(string c)
{
switch (c)
{
case "tr": return 0;
case "en": return 1;
case "es": return 2;
case "de": return 3;
case "fr": return 4;
case "pt": return 5;
}
return 1;
}
//---------------------------------------------------------
void CacheButtonData()
{
int n = questionButtons.Length;
questionOriginalScales = new Vector3[n];
answerOriginalScales = new Vector3[n];
questionOriginalPositions = new Vector3[n];
answerOriginalPositions = new Vector3[n];
questionScaleCo = new Coroutine[n];
answerScaleCo = new Coroutine[n];
questionEnterCo = new Coroutine[n];
answerEnterCo = new Coroutine[n];
for (int i = 0; i < n; i++)
{
if (questionButtons[i] != null)
{
questionOriginalScales[i] = questionButtons[i].transform.localScale;
questionOriginalPositions[i] = questionButtons[i].transform.localPosition;
questionButtons[i].transition = Selectable.Transition.None;
}
if (answerButtons[i] != null)
{
answerOriginalScales[i] = answerButtons[i].transform.localScale;
answerOriginalPositions[i] = answerButtons[i].transform.localPosition;
answerButtons[i].transition = Selectable.Transition.None;
}
}
}
void PrepareFeedbackText()
{
if (feedbackText == null) return;
if (feedbackOnTop)
{
Vector3 pos = feedbackText.transform.localPosition;
pos.y = feedbackTopY;
feedbackText.transform.localPosition = pos;
}
feedbackText.alignment = TextAlignmentOptions.Center;
feedbackText.fontSize = Mathf.Max(feedbackText.fontSize, feedbackFontSize);
feedbackText.text = "";
Color c = feedbackText.color;
c.a = 1f;
feedbackText.color = c;
}
//---------------------------------------------------------
void LoadRound()
{
ResetVisuals();
ResetColorMaps();
isRoundProcessing = false; // yeni round için submit tekrar aktif
var all = activeMap.ToList();
Shuffle(all);
selectedPairs = all.Take(5).ToList();
// Questions
for (int i = 0; i < 5; i++)
{
questionTexts[i].text = selectedPairs[i].Key;
int id = i;
questionButtons[i].onClick.RemoveAllListeners();
questionButtons[i].onClick.AddListener(() => SelectQuestion(id));
}
// Answers
List<string> answers = selectedPairs.Select(x => x.Value).ToList();
Shuffle(answers);
for (int i = 0; i < 5; i++)
{
answerTexts[i].text = answers[i];
int id = i;
answerButtons[i].onClick.RemoveAllListeners();
answerButtons[i].onClick.AddListener(() => SelectAnswer(id));
}
// Enter animasyonları
for (int i = 0; i < 5; i++)
{
if (questionEnterCo[i] != null) StopCoroutine(questionEnterCo[i]);
questionEnterCo[i] = StartCoroutine(ButtonEnterAnim(questionButtons[i], questionOriginalScales[i], questionOriginalPositions[i], i, -1));
if (answerEnterCo[i] != null) StopCoroutine(answerEnterCo[i]);
answerEnterCo[i] = StartCoroutine(ButtonEnterAnim(answerButtons[i], answerOriginalScales[i], answerOriginalPositions[i], i, 1));
if (questionTexts[i] != null) StartCoroutine(FadeInText(questionTexts[i]));
if (answerTexts[i] != null) StartCoroutine(FadeInText(answerTexts[i]));
}
}
//---------------------------------------------------------
void ResetVisuals()
{
for (int i = 0; i < 5; i++)
{
StopButtonAnims(i);
questionButtons[i].image.color = FullAlpha(baseColor);
answerButtons[i].image.color = FullAlpha(baseColor);
questionButtons[i].transform.localScale = questionOriginalScales[i];
answerButtons[i].transform.localScale = answerOriginalScales[i];
questionButtons[i].transform.localPosition = questionOriginalPositions[i];
answerButtons[i].transform.localPosition = answerOriginalPositions[i];
}
feedbackText.text = "";
}
void StopButtonAnims(int i)
{
if (questionScaleCo[i] != null) { StopCoroutine(questionScaleCo[i]); questionScaleCo[i] = null; }
if (answerScaleCo[i] != null) { StopCoroutine(answerScaleCo[i]); answerScaleCo[i] = null; }
if (questionEnterCo[i] != null) { StopCoroutine(questionEnterCo[i]); questionEnterCo[i] = null; }
if (answerEnterCo[i] != null) { StopCoroutine(answerEnterCo[i]); answerEnterCo[i] = null; }
}
void ResetColorMaps()
{
for (int i = 0; i < 5; i++)
{
questionToAnswer[i] = -1;
questionColorIdx[i] = -1;
answerColorIdx[i] = -1;
}
}
//---------------------------------------------------------
void SelectQuestion(int q)
{
if (isRoundProcessing || isTimeUp) return;
selectedQuestion = q;
StartScaleAnim(questionButtons, questionScaleCo, questionOriginalScales, q, questionOriginalScales[q] * selectedScale);
}
//---------------------------------------------------------
void SelectAnswer(int a)
{
if (isRoundProcessing || isTimeUp) return;
if (selectedQuestion == -1)
return;
int prevQuestion = selectedQuestion;
// Aynı cevabı tekrar tıklarsa iptal et
if (questionToAnswer[selectedQuestion] == a)
{
questionToAnswer[selectedQuestion] = -1;
questionColorIdx[selectedQuestion] = -1;
answerColorIdx[a] = -1;
RefreshColors();
selectedQuestion = -1;
ResetScaleAnim(questionButtons, questionScaleCo, questionOriginalScales, prevQuestion);
ResetScaleAnim(answerButtons, answerScaleCo, answerOriginalScales, a);
return;
}
// Bu cevap başka bir soruya atanmışsa oradan kaldır
for (int i = 0; i < 5; i++)
{
if (questionToAnswer[i] == a && i != selectedQuestion)
{
questionToAnswer[i] = -1;
questionColorIdx[i] = -1;
ResetScaleAnim(questionButtons, questionScaleCo, questionOriginalScales, i);
}
}
// Önceden seçilmiş cevabı temizle
int oldAns = questionToAnswer[selectedQuestion];
if (oldAns != -1)
{
answerColorIdx[oldAns] = -1;
ResetScaleAnim(answerButtons, answerScaleCo, answerOriginalScales, oldAns);
}
// Yeni eşleşmeyi ata
questionToAnswer[selectedQuestion] = a;
int colorIdx = selectedQuestion;
questionColorIdx[selectedQuestion] = colorIdx;
answerColorIdx[a] = colorIdx;
RefreshColors();
// pair pulse animasyonu
StartCoroutine(PairPulse(prevQuestion, a));
ResetScaleAnim(questionButtons, questionScaleCo, questionOriginalScales, prevQuestion);
selectedQuestion = -1;
}
//---------------------------------------------------------
void RefreshColors()
{
for (int i = 0; i < 5; i++)
{
questionButtons[i].image.color =
questionColorIdx[i] == -1 ? FullAlpha(baseColor) : FullAlpha(pairColors[questionColorIdx[i]]);
answerButtons[i].image.color =
answerColorIdx[i] == -1 ? FullAlpha(baseColor) : FullAlpha(pairColors[answerColorIdx[i]]);
}
}
//---------------------------------------------------------
// Butondan gelen submit
void OnSubmit()
{
// Eğer bu round zaten işleniyorsa veya süre bittiyse tekrar işleme
if (isRoundProcessing || isTimeUp)
return;
ProcessSubmit(false);
}
// Asıl hesaplamayı yapan fonksiyon
void ProcessSubmit(bool fromTimeout)
{
isRoundProcessing = true;
int roundCorrect = 0;
for (int q = 0; q < 5; q++)
{
int a = questionToAnswer[q];
if (a == -1)
{
questionButtons[q].image.color = FullAlpha(wrongColor);
StartCoroutine(ShakeButton(questionButtons[q], questionOriginalPositions[q]));
wrongCount++;
continue;
}
string qWord = questionTexts[q].text;
string correctA = activeMap[qWord];
string chosen = answerTexts[a].text;
if (chosen == correctA)
{
roundCorrect++;
correctCount++;
questionButtons[q].image.color = FullAlpha(correctColor);
answerButtons[a].image.color = FullAlpha(correctColor);
StartCoroutine(CorrectPulse(questionButtons[q], questionOriginalScales[q]));
StartCoroutine(CorrectPulse(answerButtons[a], answerOriginalScales[a]));
}
else
{
wrongCount++;
questionButtons[q].image.color = FullAlpha(wrongColor);
answerButtons[a].image.color = FullAlpha(wrongColor);
StartCoroutine(ShakeButton(questionButtons[q], questionOriginalPositions[q]));
StartCoroutine(ShakeButton(answerButtons[a], answerOriginalPositions[a]));
}
}
// Her doğru 20 puan
int gainedScore = roundCorrect * 20;
score += gainedScore;
Color feedbackColor;
if (roundCorrect == 5)
{
combo++;
feedbackText.text = combo >= 2 ? $"PERFECT! {combo}x COMBO!" : "PERFECT!";
feedbackColor = correctColor;
}
else if (roundCorrect > 0)
{
combo = 0;
feedbackText.text = "+" + gainedScore + " Puan";
feedbackColor = correctColor;
}
else
{
combo = 0;
feedbackText.text = "Try again!";
feedbackColor = wrongColor;
}
feedbackText.color = FullAlpha(feedbackColor);
if (feedbackOnTop)
{
Vector3 pos = feedbackText.transform.localPosition;
pos.y = feedbackTopY;
feedbackText.transform.localPosition = pos;
}
if (feedbackCo != null) StopCoroutine(feedbackCo);
feedbackCo = StartCoroutine(FeedbackAnim(feedbackText));
scoreText.text = score.ToString();
comboText.text = combo + "x";
if (scoreText != null) StartCoroutine(ScorePopAnim(scoreText));
if (combo > 0 && comboText != null) StartCoroutine(ComboAnim(comboText));
SaveProgress();
// Eğer bu timeout değilse ve oyun tamamen bitmediyse yeni round
if (!fromTimeout && !isTimeUp)
{
StartCoroutine(NextRound());
}
}
//---------------------------------------------------------
void SaveProgress()
{
// 🔥 Mod Select / Leaderboard ekranına direkt bağlanacak basit key
PlayerPrefs.SetInt("Mod6Skor", score);
PlayerPrefs.SetInt(modKey + "_LastScore", score);
int maxScore = PlayerPrefs.GetInt(modKey + "_MaxScore", 0);
if (score > maxScore)
PlayerPrefs.SetInt(modKey + "_MaxScore", score);
PlayerPrefs.SetInt(modKey + "_Correct", correctCount);
PlayerPrefs.SetInt(modKey + "_Wrong", wrongCount);
PlayerPrefs.Save();
}
//---------------------------------------------------------
IEnumerator NextRound()
{
yield return new WaitForSeconds(0.8f);
LoadRound();
}
IEnumerator GoResume()
{
yield return new WaitForSeconds(1f);
SceneManager.LoadScene("Mod6Resume");
}
//---------------------------------------------------------
void Shuffle<T>(List<T> list)
{
for (int i = list.Count - 1; i > 0; i--)
{
int j = Random.Range(0, i + 1);
(list[i], list[j]) = (list[j], list[i]);
}
}
// ================== ANIMATION HELPERS ==================
void StartScaleAnim(Button[] buttons, Coroutine[] coArr, Vector3[] originalScales, int idx, Vector3 targetScale)
{
if (idx < 0 || idx >= buttons.Length || buttons[idx] == null) return;
if (coArr[idx] != null)
StopCoroutine(coArr[idx]);
coArr[idx] = StartCoroutine(ScaleButton(buttons[idx], targetScale, idx, coArr));
}
void ResetScaleAnim(Button[] buttons, Coroutine[] coArr, Vector3[] originalScales, int idx)
{
if (idx < 0 || idx >= buttons.Length || buttons[idx] == null) return;
StartScaleAnim(buttons, coArr, originalScales, idx, originalScales[idx]);
}
IEnumerator ScaleButton(Button btn, Vector3 targetScale, int idx, Coroutine[] coArr)
{
if (btn == null) yield break;
Vector3 startScale = btn.transform.localScale;
float t = 0f;
while (t < 1f)
{
t += Time.deltaTime / Mathf.Max(0.01f, selectAnimTime);
btn.transform.localScale = Vector3.Lerp(startScale, targetScale, EaseOutQuad(t));
yield return null;
}
btn.transform.localScale = targetScale;
coArr[idx] = null;
}
IEnumerator ButtonEnterAnim(Button btn, Vector3 targetScale, Vector3 targetPos, int delayIndex, int sideSign)
{
if (btn == null) yield break;
yield return new WaitForSeconds(delayIndex * 0.05f);
Vector3 startPos = targetPos + new Vector3(sideSign * 40f, 0f, 0f);
Vector3 startScale = targetScale * 0.85f;
btn.transform.localPosition = startPos;
btn.transform.localScale = startScale;
float t = 0f;
while (t < 1f)
{
t += Time.deltaTime / Mathf.Max(0.01f, enterAnimTime);
float ease = EaseOutBack(t);
btn.transform.localPosition = Vector3.Lerp(startPos, targetPos, ease);
btn.transform.localScale = Vector3.Lerp(startScale, targetScale, ease);
yield return null;
}
btn.transform.localPosition = targetPos;
btn.transform.localScale = targetScale;
}
IEnumerator PairPulse(int questionIdx, int answerIdx)
{
if (questionIdx >= 0 && questionIdx < questionButtons.Length)
yield return StartCoroutine(QuickPulse(questionButtons[questionIdx].transform, questionOriginalScales[questionIdx]));
if (answerIdx >= 0 && answerIdx < answerButtons.Length)
yield return StartCoroutine(QuickPulse(answerButtons[answerIdx].transform, answerOriginalScales[answerIdx]));
}
IEnumerator QuickPulse(Transform tr, Vector3 normal)
{
if (tr == null) yield break;
Vector3 big = normal * 1.08f;
float t = 0f;
while (t < 1f)
{
t += Time.deltaTime / 0.08f;
tr.localScale = Vector3.Lerp(normal, big, EaseOutQuad(t));
yield return null;
}
t = 0f;
while (t < 1f)
{
t += Time.deltaTime / 0.08f;
tr.localScale = Vector3.Lerp(big, normal, EaseOutQuad(t));
yield return null;
}
tr.localScale = normal;
}
IEnumerator CorrectPulse(Button btn, Vector3 normal)
{
if (btn == null) yield break;
Vector3 big = normal * 1.12f;
float t = 0f;
while (t < 1f)
{
t += Time.deltaTime / 0.12f;
btn.transform.localScale = Vector3.Lerp(normal, big, EaseOutQuad(t));
yield return null;
}
t = 0f;
while (t < 1f)
{
t += Time.deltaTime / 0.12f;
btn.transform.localScale = Vector3.Lerp(big, normal, EaseOutQuad(t));
yield return null;
}
btn.transform.localScale = normal;
}
IEnumerator ShakeButton(Button btn, Vector3 origin)
{
if (btn == null) yield break;
float duration = 0.35f;
float magnitude = 12f;
float elapsed = 0f;
while (elapsed < duration)
{
float power = 1f - elapsed / duration;
float x = Random.Range(-1f, 1f) * magnitude * power;
btn.transform.localPosition = origin + new Vector3(x, 0f, 0f);
elapsed += Time.deltaTime;
yield return null;
}
btn.transform.localPosition = origin;
}
IEnumerator FeedbackAnim(TMP_Text txt)
{
if (txt == null) yield break;
Vector3 originalScale = Vector3.one;
Vector3 bigScale = originalScale * 1.18f;
Color c = FullAlpha(txt.color);
c.a = 0f;
txt.color = c;
Vector3 originalPos = txt.transform.localPosition;
Vector3 startPos = originalPos + Vector3.down * 18f;
txt.transform.localPosition = startPos;
float t = 0f;
while (t < 1f)
{
t += Time.deltaTime / 0.16f;
float ease = EaseOutBack(t);
txt.transform.localScale = Vector3.Lerp(originalScale, bigScale, ease);
txt.transform.localPosition = Vector3.Lerp(startPos, originalPos, ease);
c.a = Mathf.Clamp01(t);
txt.color = c;
yield return null;
}
c.a = 1f;
txt.color = c;
txt.transform.localPosition = originalPos;
t = 0f;
while (t < 1f)
{
t += Time.deltaTime / 0.12f;
txt.transform.localScale = Vector3.Lerp(bigScale, originalScale, EaseOutQuad(t));
yield return null;
}
txt.transform.localScale = originalScale;
feedbackCo = null;
}
IEnumerator ComboAnim(TMP_Text txt)
{
if (txt == null) yield break;
Vector3 original = Vector3.one;
Vector3 big = original * 1.22f;
Color baseC = FullAlpha(txt.color);
Color highlight = new Color32(255, 220, 50, 255);
float t = 0f;
while (t < 1f)
{
t += Time.deltaTime / 0.12f;
txt.transform.localScale = Vector3.Lerp(original, big, EaseOutBack(t));
txt.color = FullAlpha(Color.Lerp(baseC, highlight, t));
yield return null;
}
t = 0f;
while (t < 1f)
{
t += Time.deltaTime / 0.14f;
txt.transform.localScale = Vector3.Lerp(big, original, EaseOutQuad(t));
txt.color = FullAlpha(Color.Lerp(highlight, baseC, t));
yield return null;
}
txt.transform.localScale = original;
txt.color = baseC;
}
IEnumerator ScorePopAnim(TMP_Text txt)
{
if (txt == null) yield break;
Vector3 original = Vector3.one;
Vector3 big = original * 1.18f;
float t = 0f;
while (t < 1f)
{
t += Time.deltaTime / 0.10f;
txt.transform.localScale = Vector3.Lerp(original, big, EaseOutQuad(t));
yield return null;
}
t = 0f;
while (t < 1f)
{
t += Time.deltaTime / 0.12f;
txt.transform.localScale = Vector3.Lerp(big, original, EaseOutQuad(t));
yield return null;
}
txt.transform.localScale = original;
}
IEnumerator FadeInText(TMP_Text txt)
{
if (txt == null) yield break;
Color c = FullAlpha(txt.color);
c.a = 0f;
txt.color = c;
float t = 0f;
while (t < 1f)
{
t += Time.deltaTime / 0.18f;
c.a = EaseOutQuad(t);
txt.color = c;
yield return null;
}
c.a = 1f;
txt.color = c;
}
Color FullAlpha(Color c)
{
c.a = 1f;
return c;
}
float EaseOutBack(float t)
{
t = Mathf.Clamp01(t);
float c1 = 1.70158f;
float c3 = c1 + 1f;
return 1f + c3 * Mathf.Pow(t - 1f, 3f) + c1 * Mathf.Pow(t - 1f, 2f);
}
float EaseOutQuad(float t)
{
t = Mathf.Clamp01(t);
return 1f - (1f - t) * (1f - t);
}
}

View file

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 8009dfdd6ea39fb4e8299d3815d05377

View file

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: ec4dd0c0e48b6d445aac4329391489cc
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,152 @@
using System.Collections;
using TMPro;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
public class Mod8Resume : MonoBehaviour
{
[Header("UI TEXTS")]
public TMP_Text scoreText;
public TMP_Text maxScoreText;
public TMP_Text correctText;
public TMP_Text wrongText;
[Header("BUTTONS")]
public Button retryButton;
public Button exitButton;
[Header("AUDIO")]
public AudioSource sfx;
public AudioClip clickSound;
[Header("━━━ ANIMATION SETTINGS ━━━━━━━━━━━━━━━━━")]
public float countUpDuration = 0.8f;
public float popInDelay = 0.08f;
public float popInTime = 0.3f;
private string modKey = "Mod8_Antonym";
private int score;
private int maxScore;
private int correct;
private int wrong;
// ============================================================
void Start()
{
LoadResults();
PrepareTexts();
if (retryButton != null)
retryButton.onClick.AddListener(() => { PlaySFX(); Retry(); });
if (exitButton != null)
exitButton.onClick.AddListener(() => { PlaySFX(); ExitToMenu(); });
StartCoroutine(PlayRevealSequence());
}
// ============================================================
void LoadResults()
{
score = PlayerPrefs.GetInt(modKey + "_LastScore", 0);
maxScore = PlayerPrefs.GetInt(modKey + "_MaxScore", 0);
correct = PlayerPrefs.GetInt(modKey + "_Correct", 0);
wrong = PlayerPrefs.GetInt(modKey + "_Wrong", 0);
Debug.Log($"[MOD8 RESULT] Score={score} | Max={maxScore} | Correct={correct} | Wrong={wrong}");
}
// ============================================================
void PrepareTexts()
{
SetTextZero(scoreText);
SetTextZero(maxScoreText);
SetTextZero(correctText);
SetTextZero(wrongText);
}
void SetTextZero(TMP_Text txt)
{
if (txt == null) return;
txt.text = "0";
txt.transform.localScale = Vector3.zero;
}
// ============================================================
IEnumerator PlayRevealSequence()
{
yield return StartCoroutine(RevealStat(scoreText, score));
yield return new WaitForSeconds(popInDelay);
yield return StartCoroutine(RevealStat(maxScoreText, maxScore));
yield return new WaitForSeconds(popInDelay);
yield return StartCoroutine(RevealStat(correctText, correct));
yield return new WaitForSeconds(popInDelay);
yield return StartCoroutine(RevealStat(wrongText, wrong));
}
IEnumerator RevealStat(TMP_Text txt, int targetValue)
{
if (txt == null) yield break;
float t = 0f;
while (t < 1f)
{
t += Time.deltaTime / Mathf.Max(0.01f, popInTime);
txt.transform.localScale = Vector3.Lerp(Vector3.zero, Vector3.one, EaseOutBack(t));
if (targetValue == 0) txt.text = "0";
yield return null;
}
txt.transform.localScale = Vector3.one;
if (targetValue > 0)
{
float ct = 0f;
while (ct < 1f)
{
ct += Time.deltaTime / Mathf.Max(0.01f, countUpDuration);
txt.text = Mathf.RoundToInt(Mathf.Lerp(0, targetValue, EaseOutQuad(ct))).ToString();
yield return null;
}
}
txt.text = targetValue.ToString();
}
// ============================================================
void PlaySFX()
{
if (sfx != null && clickSound != null)
sfx.PlayOneShot(clickSound);
}
// ============================================================
void Retry()
{
SceneManager.LoadScene("Mod8");
}
// ============================================================
void ExitToMenu()
{
SceneManager.LoadScene("Anamen");
}
// ============================================================
float EaseOutBack(float t)
{
t = Mathf.Clamp01(t);
float c1 = 1.70158f, c3 = c1 + 1f;
return 1f + c3 * Mathf.Pow(t - 1f, 3f) + c1 * Mathf.Pow(t - 1f, 2f);
}
float EaseOutQuad(float t)
{
t = Mathf.Clamp01(t);
return 1f - (1f - t) * (1f - t);
}
}

View file

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 2aa39617cac61c542b3904ef06fefa38

View file

@ -0,0 +1,876 @@
using UnityEngine;
using UnityEngine.UI;
using TMPro;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine.SceneManagement;
public class WordMatchMod8 : MonoBehaviour
{
[Header("UI - QUESTIONS (LEFT)")]
[SerializeField] private Button[] questionButtons;
[SerializeField] private TMP_Text[] questionTexts;
[Header("UI - ANSWERS (RIGHT)")]
[SerializeField] private Button[] answerButtons;
[SerializeField] private TMP_Text[] answerTexts;
[Header("UI - OTHER")]
[SerializeField] private Button submitButton;
[SerializeField] private TMP_Text scoreText;
[SerializeField] private TMP_Text comboText;
[SerializeField] private TMP_Text timeText;
[SerializeField] private TMP_Text feedbackText;
[Header("━━━ BACK BUTTON ━━━━━━━━━━━━━━━━━━━━━━━━")]
public Button backButton;
public string backSceneName = "ModSec 8";
[Header("WORD DATA")]
[SerializeField] private TextAsset wordFile;
[Header("COLORS")]
public Color baseColor = new Color32(230, 230, 230, 255);
public Color[] pairColors = new Color[]
{
new Color32(120,180,255,255),
new Color32(255,200,120,255),
new Color32(160,255,160,255),
new Color32(255,150,150,255),
new Color32(210,150,255,255),
};
public Color correctColor = new Color32(0, 160, 0, 255);
public Color wrongColor = new Color32(200, 0, 0, 255);
[Header("━━━ FEEDBACK TEXT SETTINGS ━━━━━━━━━━━━━")]
public bool feedbackOnTop = true;
public float feedbackTopY = 400f;
public float feedbackFontSize = 72f;
[Header("━━━ ANIMATION SETTINGS ━━━━━━━━━━━━━━━━━")]
[Range(0.80f, 1f)] public float selectedScale = 0.94f;
public float selectAnimTime = 0.10f;
public float enterAnimTime = 0.22f;
Dictionary<string, string> activeMap = new Dictionary<string, string>();
private int[] questionToAnswer = new int[5];
private int[] questionColorIdx = new int[5];
private int[] answerColorIdx = new int[5];
private int selectedQuestion = -1;
private float timeLeft = 90f;
private bool isTimeUp = false;
private bool isRoundProcessing = false;
private int score = 0;
private int combo = 0;
private int correctCount = 0;
private int wrongCount = 0;
private string modKey = "Mod8_Antonym";
private string qLang;
private List<KeyValuePair<string, string>> selectedPairs = new List<KeyValuePair<string, string>>();
readonly Color timerNormalColor = Color.white;
readonly Color timerWarnColor = new Color32(255, 80, 80, 255);
Vector3[] questionOriginalScales;
Vector3[] answerOriginalScales;
Vector3[] questionOriginalPositions;
Vector3[] answerOriginalPositions;
Coroutine[] questionScaleCo;
Coroutine[] answerScaleCo;
Coroutine[] questionEnterCo;
Coroutine[] answerEnterCo;
Coroutine feedbackCo;
// ---------------------------------------------------------
void Start()
{
qLang = PlayerPrefs.GetString("QuestionLangCode", "en");
LoadWordFile();
CacheButtonData();
PrepareFeedbackText();
if (submitButton != null)
{
submitButton.onClick.RemoveAllListeners();
submitButton.onClick.AddListener(OnSubmit);
}
if (backButton != null)
{
backButton.onClick.RemoveAllListeners();
backButton.onClick.AddListener(() => SceneManager.LoadScene(backSceneName));
}
ResetColorMaps();
LoadRound();
scoreText.text = score.ToString();
comboText.text = combo + "x";
timeLeft = 90f;
isTimeUp = false;
}
// ---------------------------------------------------------
void Update()
{
if (isTimeUp)
{
UpdateTimerUI();
return;
}
timeLeft -= Time.deltaTime;
if (timeLeft < 0f) timeLeft = 0f;
UpdateTimerUI();
if (timeLeft <= 0f)
{
isTimeUp = true;
ProcessSubmit(true);
StartCoroutine(GoResume());
}
}
// ---------------------------------------------------------
void UpdateTimerUI()
{
if (timeText == null) return;
timeText.text = Mathf.CeilToInt(timeLeft).ToString();
if (timeLeft <= 10f)
{
timeText.color = FullAlpha(Color.Lerp(timerWarnColor, Color.white, Mathf.PingPong(Time.time * 3f, 1f)));
timeText.transform.localScale = Vector3.one * (1f + Mathf.Sin(Time.time * 10f) * 0.05f);
}
else
{
timeText.color = FullAlpha(timerNormalColor);
timeText.transform.localScale = Vector3.one;
}
}
// ---------------------------------------------------------
void LoadWordFile()
{
activeMap.Clear();
if (wordFile == null)
{
Debug.LogError("Mod8: wordFile atanmadı!");
return;
}
string[] lines = wordFile.text.Split('\n');
int li = LangIndex(qLang);
for (int i = 0; i + 1 < lines.Length; i += 2)
{
string A = lines[i].Trim();
string B = lines[i + 1].Trim();
if (string.IsNullOrWhiteSpace(A) || string.IsNullOrWhiteSpace(B)) continue;
if (!A.Contains(",") || !B.Contains(",")) continue;
string[] wA = A.Split(',');
string[] wB = B.Split(',');
if (wA.Length < 6 || wB.Length < 6) continue;
string q = wA[li].Trim();
string a = wB[li].Trim();
if (!activeMap.ContainsKey(q))
activeMap.Add(q, a);
}
}
int LangIndex(string c)
{
switch (c)
{
case "tr": return 0;
case "en": return 1;
case "es": return 2;
case "de": return 3;
case "fr": return 4;
case "pt": return 5;
}
return 1;
}
// ---------------------------------------------------------
void CacheButtonData()
{
int n = questionButtons.Length;
questionOriginalScales = new Vector3[n];
answerOriginalScales = new Vector3[n];
questionOriginalPositions = new Vector3[n];
answerOriginalPositions = new Vector3[n];
questionScaleCo = new Coroutine[n];
answerScaleCo = new Coroutine[n];
questionEnterCo = new Coroutine[n];
answerEnterCo = new Coroutine[n];
for (int i = 0; i < n; i++)
{
if (questionButtons[i] != null)
{
questionOriginalScales[i] = questionButtons[i].transform.localScale;
questionOriginalPositions[i] = questionButtons[i].transform.localPosition;
questionButtons[i].transition = Selectable.Transition.None;
}
if (answerButtons[i] != null)
{
answerOriginalScales[i] = answerButtons[i].transform.localScale;
answerOriginalPositions[i] = answerButtons[i].transform.localPosition;
answerButtons[i].transition = Selectable.Transition.None;
}
}
}
void PrepareFeedbackText()
{
if (feedbackText == null) return;
if (feedbackOnTop)
{
Vector3 pos = feedbackText.transform.localPosition;
pos.y = feedbackTopY;
feedbackText.transform.localPosition = pos;
}
feedbackText.alignment = TextAlignmentOptions.Center;
feedbackText.fontSize = Mathf.Max(feedbackText.fontSize, feedbackFontSize);
feedbackText.text = "";
Color c = feedbackText.color;
c.a = 1f;
feedbackText.color = c;
}
// ---------------------------------------------------------
void LoadRound()
{
ResetVisuals();
ResetColorMaps();
isRoundProcessing = false;
var all = activeMap.ToList();
Shuffle(all);
selectedPairs = all.Take(5).ToList();
for (int i = 0; i < 5; i++)
{
questionTexts[i].text = selectedPairs[i].Key;
int id = i;
questionButtons[i].onClick.RemoveAllListeners();
questionButtons[i].onClick.AddListener(() => SelectQuestion(id));
}
List<string> answers = selectedPairs.Select(p => p.Value).ToList();
Shuffle(answers);
for (int i = 0; i < 5; i++)
{
answerTexts[i].text = answers[i];
int id = i;
answerButtons[i].onClick.RemoveAllListeners();
answerButtons[i].onClick.AddListener(() => SelectAnswer(id));
}
// Enter animasyonları
for (int i = 0; i < 5; i++)
{
if (questionEnterCo[i] != null) StopCoroutine(questionEnterCo[i]);
questionEnterCo[i] = StartCoroutine(ButtonEnterAnim(questionButtons[i], questionOriginalScales[i], questionOriginalPositions[i], i, -1));
if (answerEnterCo[i] != null) StopCoroutine(answerEnterCo[i]);
answerEnterCo[i] = StartCoroutine(ButtonEnterAnim(answerButtons[i], answerOriginalScales[i], answerOriginalPositions[i], i, 1));
if (questionTexts[i] != null) StartCoroutine(FadeInText(questionTexts[i]));
if (answerTexts[i] != null) StartCoroutine(FadeInText(answerTexts[i]));
}
}
// ---------------------------------------------------------
void ResetVisuals()
{
for (int i = 0; i < 5; i++)
{
StopButtonAnims(i);
questionButtons[i].image.color = FullAlpha(baseColor);
answerButtons[i].image.color = FullAlpha(baseColor);
questionButtons[i].transform.localScale = questionOriginalScales[i];
answerButtons[i].transform.localScale = answerOriginalScales[i];
questionButtons[i].transform.localPosition = questionOriginalPositions[i];
answerButtons[i].transform.localPosition = answerOriginalPositions[i];
}
if (feedbackText != null)
feedbackText.text = "";
}
void StopButtonAnims(int i)
{
if (questionScaleCo[i] != null) { StopCoroutine(questionScaleCo[i]); questionScaleCo[i] = null; }
if (answerScaleCo[i] != null) { StopCoroutine(answerScaleCo[i]); answerScaleCo[i] = null; }
if (questionEnterCo[i] != null) { StopCoroutine(questionEnterCo[i]); questionEnterCo[i] = null; }
if (answerEnterCo[i] != null) { StopCoroutine(answerEnterCo[i]); answerEnterCo[i] = null; }
}
void ResetColorMaps()
{
for (int i = 0; i < 5; i++)
{
questionToAnswer[i] = -1;
questionColorIdx[i] = -1;
answerColorIdx[i] = -1;
}
}
// ---------------------------------------------------------
void SelectQuestion(int q)
{
if (isRoundProcessing || isTimeUp) return;
selectedQuestion = q;
StartScaleAnim(questionButtons, questionScaleCo, questionOriginalScales, q, questionOriginalScales[q] * selectedScale);
}
void SelectAnswer(int a)
{
if (isRoundProcessing || isTimeUp) return;
if (selectedQuestion == -1) return;
int prevQuestion = selectedQuestion;
if (questionToAnswer[selectedQuestion] == a)
{
questionToAnswer[selectedQuestion] = -1;
questionColorIdx[selectedQuestion] = -1;
answerColorIdx[a] = -1;
RefreshColors();
selectedQuestion = -1;
ResetScaleAnim(questionButtons, questionScaleCo, questionOriginalScales, prevQuestion);
ResetScaleAnim(answerButtons, answerScaleCo, answerOriginalScales, a);
return;
}
for (int i = 0; i < 5; i++)
{
if (questionToAnswer[i] == a && i != selectedQuestion)
{
questionToAnswer[i] = -1;
questionColorIdx[i] = -1;
ResetScaleAnim(questionButtons, questionScaleCo, questionOriginalScales, i);
}
}
int oldA = questionToAnswer[selectedQuestion];
if (oldA != -1)
{
answerColorIdx[oldA] = -1;
ResetScaleAnim(answerButtons, answerScaleCo, answerOriginalScales, oldA);
}
questionToAnswer[selectedQuestion] = a;
int c = selectedQuestion % pairColors.Length;
questionColorIdx[selectedQuestion] = c;
answerColorIdx[a] = c;
RefreshColors();
StartCoroutine(PairPulse(prevQuestion, a));
ResetScaleAnim(questionButtons, questionScaleCo, questionOriginalScales, prevQuestion);
selectedQuestion = -1;
}
void RefreshColors()
{
for (int i = 0; i < 5; i++)
{
questionButtons[i].image.color =
questionColorIdx[i] == -1 ? FullAlpha(baseColor) : FullAlpha(pairColors[questionColorIdx[i]]);
answerButtons[i].image.color =
answerColorIdx[i] == -1 ? FullAlpha(baseColor) : FullAlpha(pairColors[answerColorIdx[i]]);
}
}
// ---------------------------------------------------------
void OnSubmit()
{
if (isRoundProcessing || isTimeUp) return;
ProcessSubmit(false);
}
void ProcessSubmit(bool fromTimeout)
{
isRoundProcessing = true;
int roundCorrect = 0;
for (int q = 0; q < 5; q++)
{
int a = questionToAnswer[q];
if (a == -1)
{
questionButtons[q].image.color = FullAlpha(wrongColor);
StartCoroutine(ShakeButton(questionButtons[q], questionOriginalPositions[q]));
wrongCount++;
continue;
}
string qWord = questionTexts[q].text;
string correctA = activeMap[qWord];
string chosenA = answerTexts[a].text;
if (chosenA == correctA)
{
roundCorrect++;
correctCount++;
questionButtons[q].image.color = FullAlpha(correctColor);
answerButtons[a].image.color = FullAlpha(correctColor);
StartCoroutine(CorrectPulse(questionButtons[q], questionOriginalScales[q]));
StartCoroutine(CorrectPulse(answerButtons[a], answerOriginalScales[a]));
}
else
{
wrongCount++;
questionButtons[q].image.color = FullAlpha(wrongColor);
answerButtons[a].image.color = FullAlpha(wrongColor);
StartCoroutine(ShakeButton(questionButtons[q], questionOriginalPositions[q]));
StartCoroutine(ShakeButton(answerButtons[a], answerOriginalPositions[a]));
}
}
int gained = roundCorrect * 20;
score += gained;
Color feedbackColor;
if (roundCorrect == 5)
{
combo++;
feedbackText.text = combo >= 2 ? $"PERFECT! {combo}x COMBO!" : "PERFECT!";
feedbackColor = correctColor;
}
else if (roundCorrect > 0)
{
combo = 0;
feedbackText.text = "+" + gained + " Points";
feedbackColor = correctColor;
}
else
{
combo = 0;
feedbackText.text = "Try Again!";
feedbackColor = wrongColor;
}
feedbackText.color = FullAlpha(feedbackColor);
if (feedbackOnTop)
{
Vector3 pos = feedbackText.transform.localPosition;
pos.y = feedbackTopY;
feedbackText.transform.localPosition = pos;
}
if (feedbackCo != null) StopCoroutine(feedbackCo);
feedbackCo = StartCoroutine(FeedbackAnim(feedbackText));
scoreText.text = score.ToString();
comboText.text = combo + "x";
if (scoreText != null) StartCoroutine(ScorePopAnim(scoreText));
if (combo > 0 && comboText != null) StartCoroutine(ComboAnim(comboText));
SaveProgress();
if (!fromTimeout)
StartCoroutine(NextRound());
}
// ---------------------------------------------------------
void SaveProgress()
{
// 🔥 Mod Select / Leaderboard ekranına direkt bağlanacak basit key
PlayerPrefs.SetInt("Mod8Skor", score);
PlayerPrefs.SetInt(modKey + "_LastScore", score);
int best = PlayerPrefs.GetInt(modKey + "_MaxScore", 0);
if (score > best)
PlayerPrefs.SetInt(modKey + "_MaxScore", score);
PlayerPrefs.SetInt(modKey + "_Correct", correctCount);
PlayerPrefs.SetInt(modKey + "_Wrong", wrongCount);
PlayerPrefs.Save();
}
IEnumerator NextRound()
{
yield return new WaitForSeconds(0.8f);
LoadRound();
}
IEnumerator GoResume()
{
yield return new WaitForSeconds(1f);
SceneManager.LoadScene("Mod8Resume");
}
// ---------------------------------------------------------
void Shuffle<T>(List<T> list)
{
for (int i = list.Count - 1; i > 0; i--)
{
int j = Random.Range(0, i + 1);
(list[i], list[j]) = (list[j], list[i]);
}
}
// ================== ANIMATION HELPERS ==================
void StartScaleAnim(Button[] buttons, Coroutine[] coArr, Vector3[] originalScales, int idx, Vector3 targetScale)
{
if (idx < 0 || idx >= buttons.Length || buttons[idx] == null) return;
if (coArr[idx] != null)
StopCoroutine(coArr[idx]);
coArr[idx] = StartCoroutine(ScaleButton(buttons[idx], targetScale, idx, coArr));
}
void ResetScaleAnim(Button[] buttons, Coroutine[] coArr, Vector3[] originalScales, int idx)
{
if (idx < 0 || idx >= buttons.Length || buttons[idx] == null) return;
StartScaleAnim(buttons, coArr, originalScales, idx, originalScales[idx]);
}
IEnumerator ScaleButton(Button btn, Vector3 targetScale, int idx, Coroutine[] coArr)
{
if (btn == null) yield break;
Vector3 startScale = btn.transform.localScale;
float t = 0f;
while (t < 1f)
{
t += Time.deltaTime / Mathf.Max(0.01f, selectAnimTime);
btn.transform.localScale = Vector3.Lerp(startScale, targetScale, EaseOutQuad(t));
yield return null;
}
btn.transform.localScale = targetScale;
coArr[idx] = null;
}
IEnumerator ButtonEnterAnim(Button btn, Vector3 targetScale, Vector3 targetPos, int delayIndex, int sideSign)
{
if (btn == null) yield break;
yield return new WaitForSeconds(delayIndex * 0.05f);
Vector3 startPos = targetPos + new Vector3(sideSign * 40f, 0f, 0f);
Vector3 startScale = targetScale * 0.85f;
btn.transform.localPosition = startPos;
btn.transform.localScale = startScale;
float t = 0f;
while (t < 1f)
{
t += Time.deltaTime / Mathf.Max(0.01f, enterAnimTime);
float ease = EaseOutBack(t);
btn.transform.localPosition = Vector3.Lerp(startPos, targetPos, ease);
btn.transform.localScale = Vector3.Lerp(startScale, targetScale, ease);
yield return null;
}
btn.transform.localPosition = targetPos;
btn.transform.localScale = targetScale;
}
IEnumerator PairPulse(int questionIdx, int answerIdx)
{
if (questionIdx >= 0 && questionIdx < questionButtons.Length)
yield return StartCoroutine(QuickPulse(questionButtons[questionIdx].transform, questionOriginalScales[questionIdx]));
if (answerIdx >= 0 && answerIdx < answerButtons.Length)
yield return StartCoroutine(QuickPulse(answerButtons[answerIdx].transform, answerOriginalScales[answerIdx]));
}
IEnumerator QuickPulse(Transform tr, Vector3 normal)
{
if (tr == null) yield break;
Vector3 big = normal * 1.08f;
float t = 0f;
while (t < 1f)
{
t += Time.deltaTime / 0.08f;
tr.localScale = Vector3.Lerp(normal, big, EaseOutQuad(t));
yield return null;
}
t = 0f;
while (t < 1f)
{
t += Time.deltaTime / 0.08f;
tr.localScale = Vector3.Lerp(big, normal, EaseOutQuad(t));
yield return null;
}
tr.localScale = normal;
}
IEnumerator CorrectPulse(Button btn, Vector3 normal)
{
if (btn == null) yield break;
Vector3 big = normal * 1.12f;
float t = 0f;
while (t < 1f)
{
t += Time.deltaTime / 0.12f;
btn.transform.localScale = Vector3.Lerp(normal, big, EaseOutQuad(t));
yield return null;
}
t = 0f;
while (t < 1f)
{
t += Time.deltaTime / 0.12f;
btn.transform.localScale = Vector3.Lerp(big, normal, EaseOutQuad(t));
yield return null;
}
btn.transform.localScale = normal;
}
IEnumerator ShakeButton(Button btn, Vector3 origin)
{
if (btn == null) yield break;
float duration = 0.35f;
float magnitude = 12f;
float elapsed = 0f;
while (elapsed < duration)
{
float power = 1f - elapsed / duration;
float x = Random.Range(-1f, 1f) * magnitude * power;
btn.transform.localPosition = origin + new Vector3(x, 0f, 0f);
elapsed += Time.deltaTime;
yield return null;
}
btn.transform.localPosition = origin;
}
IEnumerator FeedbackAnim(TMP_Text txt)
{
if (txt == null) yield break;
Vector3 originalScale = Vector3.one;
Vector3 bigScale = originalScale * 1.18f;
Color c = FullAlpha(txt.color);
c.a = 0f;
txt.color = c;
Vector3 originalPos = txt.transform.localPosition;
Vector3 startPos = originalPos + Vector3.down * 18f;
txt.transform.localPosition = startPos;
float t = 0f;
while (t < 1f)
{
t += Time.deltaTime / 0.16f;
float ease = EaseOutBack(t);
txt.transform.localScale = Vector3.Lerp(originalScale, bigScale, ease);
txt.transform.localPosition = Vector3.Lerp(startPos, originalPos, ease);
c.a = Mathf.Clamp01(t);
txt.color = c;
yield return null;
}
c.a = 1f;
txt.color = c;
txt.transform.localPosition = originalPos;
t = 0f;
while (t < 1f)
{
t += Time.deltaTime / 0.12f;
txt.transform.localScale = Vector3.Lerp(bigScale, originalScale, EaseOutQuad(t));
yield return null;
}
txt.transform.localScale = originalScale;
feedbackCo = null;
}
IEnumerator ComboAnim(TMP_Text txt)
{
if (txt == null) yield break;
Vector3 original = Vector3.one;
Vector3 big = original * 1.22f;
Color baseC = FullAlpha(txt.color);
Color highlight = new Color32(255, 220, 50, 255);
float t = 0f;
while (t < 1f)
{
t += Time.deltaTime / 0.12f;
txt.transform.localScale = Vector3.Lerp(original, big, EaseOutBack(t));
txt.color = FullAlpha(Color.Lerp(baseC, highlight, t));
yield return null;
}
t = 0f;
while (t < 1f)
{
t += Time.deltaTime / 0.14f;
txt.transform.localScale = Vector3.Lerp(big, original, EaseOutQuad(t));
txt.color = FullAlpha(Color.Lerp(highlight, baseC, t));
yield return null;
}
txt.transform.localScale = original;
txt.color = baseC;
}
IEnumerator ScorePopAnim(TMP_Text txt)
{
if (txt == null) yield break;
Vector3 original = Vector3.one;
Vector3 big = original * 1.18f;
float t = 0f;
while (t < 1f)
{
t += Time.deltaTime / 0.10f;
txt.transform.localScale = Vector3.Lerp(original, big, EaseOutQuad(t));
yield return null;
}
t = 0f;
while (t < 1f)
{
t += Time.deltaTime / 0.12f;
txt.transform.localScale = Vector3.Lerp(big, original, EaseOutQuad(t));
yield return null;
}
txt.transform.localScale = original;
}
IEnumerator FadeInText(TMP_Text txt)
{
if (txt == null) yield break;
Color c = FullAlpha(txt.color);
c.a = 0f;
txt.color = c;
float t = 0f;
while (t < 1f)
{
t += Time.deltaTime / 0.18f;
c.a = EaseOutQuad(t);
txt.color = c;
yield return null;
}
c.a = 1f;
txt.color = c;
}
Color FullAlpha(Color c)
{
c.a = 1f;
return c;
}
float EaseOutBack(float t)
{
t = Mathf.Clamp01(t);
float c1 = 1.70158f;
float c3 = c1 + 1f;
return 1f + c3 * Mathf.Pow(t - 1f, 3f) + c1 * Mathf.Pow(t - 1f, 2f);
}
float EaseOutQuad(float t)
{
t = Mathf.Clamp01(t);
return 1f - (1f - t) * (1f - t);
}
}

View file

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 24738b79935ff2e4684b1e2523827057

View file

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 15b1f064ebce8074c855ee805144ea4a
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,82 @@
using TMPro;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
public class Mod10Resume : MonoBehaviour
{
[Header("UI TEXTS (ONLY NUMBERS)")]
public TMP_Text scoreText;
public TMP_Text maxScoreText;
public TMP_Text correctText;
public TMP_Text wrongText;
[Header("BUTTONS")]
public Button retryButton;
public Button exitButton;
[Header("AUDIO")]
public AudioSource sfx;
public AudioClip clickSound;
// Bu modun kendi ana anahtarı
private string modKey = "Mod10";
private int score;
private int maxScore;
private int correct;
private int wrong;
void Start()
{
LoadResults();
UpdateUI();
if (retryButton != null)
retryButton.onClick.AddListener(() => { PlaySFX(); Retry(); });
if (exitButton != null)
exitButton.onClick.AddListener(() => { PlaySFX(); ExitToMenu(); });
}
// ---------------------------------------------------------------
void LoadResults()
{
score = PlayerPrefs.GetInt(modKey + "_LastScore", 0);
maxScore = PlayerPrefs.GetInt(modKey + "_MaxScore", 0);
correct = PlayerPrefs.GetInt(modKey + "_Correct", 0);
wrong = PlayerPrefs.GetInt(modKey + "_Wrong", 0);
Debug.Log("MOD10 RESULT → " +
$"Score:{score} | Max:{maxScore} | C:{correct} | W:{wrong}");
}
// ---------------------------------------------------------------
void UpdateUI()
{
if (scoreText != null) scoreText.text = score.ToString();
if (maxScoreText != null) maxScoreText.text = maxScore.ToString();
if (correctText != null) correctText.text = correct.ToString();
if (wrongText != null) wrongText.text = wrong.ToString();
}
// ---------------------------------------------------------------
void PlaySFX()
{
if (sfx && clickSound)
sfx.PlayOneShot(clickSound);
}
// ---------------------------------------------------------------
void Retry()
{
// 🔥 MOD 10 OYUN SAHNESİNE GERİ DÖNÜŞ
SceneManager.LoadScene("Mod10");
}
// ---------------------------------------------------------------
void ExitToMenu()
{
SceneManager.LoadScene("Anamen");
}
}

View file

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 943d61e94ac5fdc45b9ea6f4357d8d71

View file

@ -0,0 +1,807 @@
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
public class SentenceOrderGameScene : MonoBehaviour
{
[Header("TXT DOSYASI (6 Dil)")]
public TextAsset questionFile;
[Header("UI")]
public TMP_Text questionText;
public TMP_Text[] answerTexts;
public Button[] answerButtons;
public Button submitButton;
public TMP_Text selectedWordsText;
public TMP_Text scoreText;
public TMP_Text comboText;
public TMP_Text timerText;
public TMP_Text feedbackText;
[Header("EXTRA BUTTONS")]
public Button extraTimeButton;
public Button extraHintButton;
public Button extraSkipButton;
[Header("━━━ BACK BUTTON ━━━━━━━━━━━━━━━━━━━━━━━━")]
public Button backButton;
public string backSceneName = "ModSec 10";
[Header("RENKLER")]
public Color normalColor = new Color32(255, 255, 255, 70);
public Color selectedColor = new Color32(60, 110, 200, 255);
public Color correctColor = new Color32(0, 200, 0, 255);
public Color wrongColor = new Color32(200, 0, 0, 255);
[Header("━━━ FEEDBACK TEXT SETTINGS ━━━━━━━━━━━━━")]
public bool feedbackOnTop = true;
public float feedbackTopY = 400f;
public float feedbackFontSize = 72f;
[Header("━━━ ANIMATION SETTINGS ━━━━━━━━━━━━━━━━━")]
[Range(0.80f, 1f)] public float selectedScale = 0.94f;
public float selectAnimTime = 0.10f;
public float enterAnimTime = 0.22f;
// INTERNAL
private class SentenceEntry
{
public string[] sentence = new string[6];
}
private List<SentenceEntry> questions = new List<SentenceEntry>();
private string[] correctWords;
private string[] scrambledWords;
private int[] order;
private int selectedCount = 0;
private bool locked = false;
private int lastID = -1;
private int score = 0;
private int combo = 0;
private float timeLeft = 60f;
private float nextTimer = 0f;
// LANGUAGE & MOD KEY
private string lang;
private string modKey = "Mod10";
// Counters
private int correctCount = 0;
private int wrongCount = 0;
readonly Color timerNormalColor = Color.white;
readonly Color timerWarnColor = new Color32(255, 80, 80, 255);
Vector3[] originalButtonScales;
Vector3[] originalButtonPositions;
Coroutine[] buttonScaleCoroutines;
Coroutine[] buttonEnterCoroutines;
Coroutine feedbackCo;
// ------------------------------------------------------------
void Start()
{
lang = PlayerPrefs.GetString("QuestionLangCode", "en");
order = new int[answerButtons.Length];
if (questionFile == null)
{
Debug.LogError("SentenceOrderGameScene: TXT bağlanmamış!");
return;
}
CacheButtonData();
PrepareFeedbackText();
LoadTXT(questionFile.text);
Shuffle(questions);
submitButton.onClick.AddListener(OnSubmit);
extraTimeButton.onClick.AddListener(() => timeLeft += 5f);
extraHintButton.onClick.AddListener(OnHint);
extraSkipButton.onClick.AddListener(() => NextQuestion());
if (backButton != null)
{
backButton.onClick.RemoveAllListeners();
backButton.onClick.AddListener(() => SceneManager.LoadScene(backSceneName));
}
scoreText.text = "0";
comboText.text = "0x";
NextQuestion();
}
// ------------------------------------------------------------
void Update()
{
if (!locked)
{
timeLeft -= Time.deltaTime;
if (timeLeft <= 0)
{
timeLeft = 0;
GameOver();
}
}
UpdateTimerUI();
if (locked && nextTimer > 0)
{
nextTimer -= Time.deltaTime;
if (nextTimer <= 0)
NextQuestion();
}
}
// ------------------------------------------------------------
void CacheButtonData()
{
if (answerButtons == null) return;
int len = answerButtons.Length;
originalButtonScales = new Vector3[len];
originalButtonPositions = new Vector3[len];
buttonScaleCoroutines = new Coroutine[len];
buttonEnterCoroutines = new Coroutine[len];
for (int i = 0; i < len; i++)
{
if (answerButtons[i] == null) continue;
originalButtonScales[i] = answerButtons[i].transform.localScale;
originalButtonPositions[i] = answerButtons[i].transform.localPosition;
answerButtons[i].transition = Selectable.Transition.None;
}
}
void PrepareFeedbackText()
{
if (feedbackText == null) return;
if (feedbackOnTop)
{
Vector3 pos = feedbackText.transform.localPosition;
pos.y = feedbackTopY;
feedbackText.transform.localPosition = pos;
}
feedbackText.alignment = TextAlignmentOptions.Center;
feedbackText.fontSize = Mathf.Max(feedbackText.fontSize, feedbackFontSize);
feedbackText.text = "";
Color c = feedbackText.color;
c.a = 1f;
feedbackText.color = c;
}
void UpdateTimerUI()
{
if (timerText == null) return;
timerText.text = Mathf.Ceil(timeLeft).ToString();
if (timeLeft <= 10f)
{
timerText.color = FullAlpha(Color.Lerp(timerWarnColor, Color.white, Mathf.PingPong(Time.time * 3f, 1f)));
timerText.transform.localScale = Vector3.one * (1f + Mathf.Sin(Time.time * 10f) * 0.05f);
}
else
{
timerText.color = FullAlpha(timerNormalColor);
timerText.transform.localScale = Vector3.one;
}
}
// ------------------------------------------------------------
void LoadTXT(string raw)
{
foreach (string line in raw.Trim().Split('\n'))
{
if (string.IsNullOrWhiteSpace(line)) continue;
string[] p = line.Split(',');
if (p.Length < 6) continue;
SentenceEntry e = new SentenceEntry();
for (int i = 0; i < 6; i++)
e.sentence[i] = p[i].Trim();
questions.Add(e);
}
}
// ------------------------------------------------------------
void NextQuestion()
{
nextTimer = 0f;
locked = false;
selectedCount = 0;
if (feedbackText != null)
feedbackText.text = "";
if (selectedWordsText != null)
selectedWordsText.text = "";
for (int i = 0; i < order.Length; i++)
order[i] = 0;
for (int i = 0; i < answerButtons.Length; i++)
{
StopButtonCoroutines(i);
answerButtons[i].interactable = true;
answerButtons[i].image.color = FullAlpha(normalColor);
answerButtons[i].transform.localScale = originalButtonScales[i];
answerButtons[i].transform.localPosition = originalButtonPositions[i];
answerButtons[i].gameObject.SetActive(false);
}
// random
int qID = Random.Range(0, questions.Count);
if (qID == lastID && questions.Count > 1)
qID = (qID + 1) % questions.Count;
lastID = qID;
SentenceEntry entry = questions[qID];
int L = GetLangIndex();
string s = entry.sentence[L];
questionText.text = s;
StartCoroutine(FadeInText(questionText));
correctWords = s.Split(' ');
int wc = Mathf.Min(correctWords.Length, answerButtons.Length);
System.Array.Resize(ref correctWords, wc);
scrambledWords = (string[])correctWords.Clone();
Shuffle(scrambledWords);
for (int i = 0; i < wc; i++)
{
answerButtons[i].gameObject.SetActive(true);
answerTexts[i].text = scrambledWords[i];
int id = i;
answerButtons[i].onClick.RemoveAllListeners();
answerButtons[i].onClick.AddListener(() => OnClickWord(id));
buttonEnterCoroutines[i] = StartCoroutine(ButtonEnterAnim(answerButtons[i], i));
}
}
// ------------------------------------------------------------
void OnClickWord(int id)
{
if (locked) return;
int wc = correctWords.Length;
if (order[id] != 0)
{
int old = order[id];
order[id] = 0;
for (int i = 0; i < wc; i++)
if (order[i] > old)
order[i]--;
selectedCount--;
}
else
{
selectedCount++;
order[id] = selectedCount;
}
RefreshUI();
}
// ------------------------------------------------------------
void RefreshUI()
{
int wc = correctWords.Length;
List<string> seq = new List<string>();
for (int i = 0; i < wc; i++)
{
if (order[i] > 0)
{
answerButtons[i].image.color = FullAlpha(selectedColor);
answerTexts[i].text = order[i] + ". " + scrambledWords[i];
StartScaleAnim(i, originalButtonScales[i] * selectedScale);
}
else
{
answerButtons[i].image.color = FullAlpha(normalColor);
answerTexts[i].text = scrambledWords[i];
StartScaleAnim(i, originalButtonScales[i]);
}
}
for (int orderNum = 1; orderNum <= wc; orderNum++)
for (int j = 0; j < wc; j++)
if (order[j] == orderNum)
seq.Add(scrambledWords[j]);
if (selectedWordsText != null)
selectedWordsText.text = string.Join(" | ", seq);
}
// ------------------------------------------------------------
void OnSubmit()
{
if (locked) return;
int wc = correctWords.Length;
if (selectedCount < wc)
{
SetFeedback("Select all words!", wrongColor);
return;
}
locked = true;
bool ok = true;
for (int orderNum = 1; orderNum <= wc; orderNum++)
for (int i = 0; i < wc; i++)
if (order[i] == orderNum && scrambledWords[i] != correctWords[orderNum - 1])
ok = false;
for (int i = 0; i < wc; i++)
answerButtons[i].interactable = false;
if (ok)
{
correctCount++;
combo++;
score += 50 + (combo - 1) * 10;
timeLeft += 2f;
for (int i = 0; i < wc; i++)
{
answerButtons[i].image.color = FullAlpha(correctColor);
StartCoroutine(CorrectPulse(answerButtons[i], i));
}
SetFeedback(combo >= 3 ? $"TRUE {combo}x COMBO!" : "TRUE", correctColor);
if (comboText != null) StartCoroutine(ComboAnim(comboText));
}
else
{
wrongCount++;
combo = 0;
for (int i = 0; i < wc; i++)
{
answerButtons[i].image.color = FullAlpha(wrongColor);
StartCoroutine(ShakeButton(answerButtons[i], i));
}
SetFeedback("FALSE", wrongColor);
}
scoreText.text = score.ToString();
comboText.text = combo + "x";
if (scoreText != null) StartCoroutine(ScorePopAnim(scoreText));
nextTimer = 1f;
}
// ------------------------------------------------------------
// HINT: İlk kelimeyi otomatik seçer
// ------------------------------------------------------------
void OnHint()
{
if (locked) return;
int wc = correctWords.Length;
// Önce tüm seçimleri sıfırla
selectedCount = 0;
for (int i = 0; i < wc; i++)
order[i] = 0;
// Doğru ilk kelime
string firstWord = correctWords[0];
// Scrambled içinde doğru kelimenin index'ini bul
for (int i = 0; i < wc; i++)
{
if (scrambledWords[i] == firstWord)
{
order[i] = 1;
selectedCount = 1;
StartCoroutine(CorrectPulse(answerButtons[i], i));
break;
}
}
RefreshUI();
SetFeedback("Hint used!", selectedColor);
}
// ------------------------------------------------------------
void SetFeedback(string msg, Color c)
{
if (feedbackText == null) return;
feedbackText.text = msg;
feedbackText.color = FullAlpha(c);
if (feedbackOnTop)
{
Vector3 pos = feedbackText.transform.localPosition;
pos.y = feedbackTopY;
feedbackText.transform.localPosition = pos;
}
if (feedbackCo != null) StopCoroutine(feedbackCo);
feedbackCo = StartCoroutine(FeedbackAnim(feedbackText));
}
// ------------------------------------------------------------
void GameOver()
{
// 🔥 Mod Select / Leaderboard ekranına direkt bağlanacak basit key
PlayerPrefs.SetInt("Mod10Skor", score);
// kayıt sistemi
PlayerPrefs.SetString("LastPlayedMod", modKey);
PlayerPrefs.SetInt(modKey + "_LastScore", score);
int oldMax = PlayerPrefs.GetInt(modKey + "_MaxScore", 0);
if (score > oldMax)
PlayerPrefs.SetInt(modKey + "_MaxScore", score);
PlayerPrefs.SetInt(modKey + "_Correct", correctCount);
PlayerPrefs.SetInt(modKey + "_Wrong", wrongCount);
PlayerPrefs.Save();
// 🔥 MOD 10 SONUÇ SAHNESİ
SceneManager.LoadScene("Mod10Resume");
}
// ------------------------------------------------------------
int GetLangIndex()
{
return lang switch
{
"tr" => 0,
"en" => 1,
"es" => 2,
"de" => 3,
"fr" => 4,
"pt" => 5,
_ => 1
};
}
// ------------------------------------------------------------
void Shuffle<T>(IList<T> arr)
{
for (int i = 0; i < arr.Count; i++)
{
int r = Random.Range(i, arr.Count);
(arr[i], arr[r]) = (arr[r], arr[i]);
}
}
// ================== ANIMATION HELPERS ==================
void StartScaleAnim(int index, Vector3 targetScale)
{
if (index < 0 || index >= answerButtons.Length) return;
if (answerButtons[index] == null) return;
if (buttonScaleCoroutines[index] != null)
StopCoroutine(buttonScaleCoroutines[index]);
buttonScaleCoroutines[index] = StartCoroutine(ScaleButton(answerButtons[index], targetScale));
}
void StopButtonCoroutines(int index)
{
if (buttonScaleCoroutines != null && index < buttonScaleCoroutines.Length && buttonScaleCoroutines[index] != null)
{
StopCoroutine(buttonScaleCoroutines[index]);
buttonScaleCoroutines[index] = null;
}
if (buttonEnterCoroutines != null && index < buttonEnterCoroutines.Length && buttonEnterCoroutines[index] != null)
{
StopCoroutine(buttonEnterCoroutines[index]);
buttonEnterCoroutines[index] = null;
}
}
IEnumerator ScaleButton(Button btn, Vector3 targetScale)
{
if (btn == null) yield break;
Vector3 startScale = btn.transform.localScale;
float t = 0f;
while (t < 1f)
{
t += Time.deltaTime / Mathf.Max(0.01f, selectAnimTime);
btn.transform.localScale = Vector3.Lerp(startScale, targetScale, EaseOutQuad(t));
yield return null;
}
btn.transform.localScale = targetScale;
}
IEnumerator ButtonEnterAnim(Button btn, int delayIndex)
{
if (btn == null) yield break;
int idx = System.Array.IndexOf(answerButtons, btn);
if (idx < 0) yield break;
yield return new WaitForSeconds(delayIndex * 0.05f);
Vector3 targetPos = originalButtonPositions[idx];
Vector3 startPos = targetPos + Vector3.up * 30f;
Vector3 targetScale = originalButtonScales[idx];
Vector3 startScale = targetScale * 0.85f;
btn.transform.localPosition = startPos;
btn.transform.localScale = startScale;
float t = 0f;
while (t < 1f)
{
t += Time.deltaTime / Mathf.Max(0.01f, enterAnimTime);
float ease = EaseOutBack(t);
btn.transform.localPosition = Vector3.Lerp(startPos, targetPos, ease);
btn.transform.localScale = Vector3.Lerp(startScale, targetScale, ease);
yield return null;
}
btn.transform.localPosition = targetPos;
btn.transform.localScale = targetScale;
}
IEnumerator CorrectPulse(Button btn, int idx)
{
if (btn == null) yield break;
if (idx < 0 || idx >= originalButtonScales.Length) yield break;
Vector3 normal = originalButtonScales[idx];
Vector3 big = normal * 1.12f;
float t = 0f;
while (t < 1f)
{
t += Time.deltaTime / 0.12f;
btn.transform.localScale = Vector3.Lerp(normal, big, EaseOutQuad(t));
yield return null;
}
t = 0f;
while (t < 1f)
{
t += Time.deltaTime / 0.12f;
btn.transform.localScale = Vector3.Lerp(big, normal, EaseOutQuad(t));
yield return null;
}
btn.transform.localScale = normal;
}
IEnumerator ShakeButton(Button btn, int idx)
{
if (btn == null) yield break;
if (idx < 0 || idx >= originalButtonPositions.Length) yield break;
Vector3 origin = originalButtonPositions[idx];
float duration = 0.35f;
float magnitude = 12f;
float elapsed = 0f;
while (elapsed < duration)
{
float power = 1f - elapsed / duration;
float x = Random.Range(-1f, 1f) * magnitude * power;
btn.transform.localPosition = origin + new Vector3(x, 0f, 0f);
elapsed += Time.deltaTime;
yield return null;
}
btn.transform.localPosition = origin;
}
IEnumerator FeedbackAnim(TMP_Text txt)
{
if (txt == null) yield break;
Vector3 originalScale = Vector3.one;
Vector3 bigScale = originalScale * 1.18f;
Color c = FullAlpha(txt.color);
c.a = 0f;
txt.color = c;
Vector3 originalPos = txt.transform.localPosition;
Vector3 startPos = originalPos + Vector3.down * 18f;
txt.transform.localPosition = startPos;
float t = 0f;
while (t < 1f)
{
t += Time.deltaTime / 0.16f;
float ease = EaseOutBack(t);
txt.transform.localScale = Vector3.Lerp(originalScale, bigScale, ease);
txt.transform.localPosition = Vector3.Lerp(startPos, originalPos, ease);
c.a = Mathf.Clamp01(t);
txt.color = c;
yield return null;
}
c.a = 1f;
txt.color = c;
txt.transform.localPosition = originalPos;
t = 0f;
while (t < 1f)
{
t += Time.deltaTime / 0.12f;
txt.transform.localScale = Vector3.Lerp(bigScale, originalScale, EaseOutQuad(t));
yield return null;
}
txt.transform.localScale = originalScale;
feedbackCo = null;
}
IEnumerator ComboAnim(TMP_Text txt)
{
if (txt == null) yield break;
Vector3 original = Vector3.one;
Vector3 big = original * 1.22f;
Color baseColor = FullAlpha(txt.color);
Color highlight = new Color32(255, 220, 50, 255);
float t = 0f;
while (t < 1f)
{
t += Time.deltaTime / 0.12f;
txt.transform.localScale = Vector3.Lerp(original, big, EaseOutBack(t));
txt.color = FullAlpha(Color.Lerp(baseColor, highlight, t));
yield return null;
}
t = 0f;
while (t < 1f)
{
t += Time.deltaTime / 0.14f;
txt.transform.localScale = Vector3.Lerp(big, original, EaseOutQuad(t));
txt.color = FullAlpha(Color.Lerp(highlight, baseColor, t));
yield return null;
}
txt.transform.localScale = original;
txt.color = baseColor;
}
IEnumerator ScorePopAnim(TMP_Text txt)
{
if (txt == null) yield break;
Vector3 original = Vector3.one;
Vector3 big = original * 1.18f;
float t = 0f;
while (t < 1f)
{
t += Time.deltaTime / 0.10f;
txt.transform.localScale = Vector3.Lerp(original, big, EaseOutQuad(t));
yield return null;
}
t = 0f;
while (t < 1f)
{
t += Time.deltaTime / 0.12f;
txt.transform.localScale = Vector3.Lerp(big, original, EaseOutQuad(t));
yield return null;
}
txt.transform.localScale = original;
}
IEnumerator FadeInText(TMP_Text txt)
{
if (txt == null) yield break;
Color c = FullAlpha(txt.color);
c.a = 0f;
txt.color = c;
float t = 0f;
while (t < 1f)
{
t += Time.deltaTime / 0.18f;
c.a = EaseOutQuad(t);
txt.color = c;
yield return null;
}
c.a = 1f;
txt.color = c;
}
Color FullAlpha(Color c)
{
c.a = 1f;
return c;
}
float EaseOutBack(float t)
{
t = Mathf.Clamp01(t);
float c1 = 1.70158f;
float c3 = c1 + 1f;
return 1f + c3 * Mathf.Pow(t - 1f, 3f) + c1 * Mathf.Pow(t - 1f, 2f);
}
float EaseOutQuad(float t)
{
t = Mathf.Clamp01(t);
return 1f - (1f - t) * (1f - t);
}
}

View file

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 5d1f4458536ed634b97019cf3c7abb27

View file

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 5861da0019dff9a42a4a83d14f1722c8
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,846 @@
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
public class AnalogyLogicGameScene : MonoBehaviour
{
[Header("TXT (6 Language Analogy Data)")]
public TextAsset analogyFile;
[Header("UI")]
public TMP_Text questionText;
public TMP_Text[] answerTexts;
public Button[] answerButtons;
public Button submitButton;
public TMP_Text feedbackText;
public TMP_Text scoreText;
public TMP_Text comboText;
public TMP_Text timerText;
public TMP_Text selectedWordsText;
[Header("EXTRAS")]
public Button extraTimeButton;
public Button extraHintButton;
public Button extraSkipButton;
[Header("━━━ BACK BUTTON ━━━━━━━━━━━━━━━━━━━━━━━━")]
public Button backButton;
public string backSceneName = "ModSec 11";
[Header("COLORS")]
public Color normalColor = new Color32(255, 255, 255, 70);
public Color selectedColor = new Color32(60, 110, 200, 255);
public Color correctColor = new Color32(0, 200, 0, 255);
public Color wrongColor = new Color32(200, 0, 0, 255);
[Header("━━━ FEEDBACK TEXT SETTINGS ━━━━━━━━━━━━━")]
public bool feedbackOnTop = true;
public float feedbackTopY = 400f;
public float feedbackFontSize = 72f;
[Header("━━━ ANIMATION SETTINGS ━━━━━━━━━━━━━━━━━")]
[Range(0.80f, 1f)] public float selectedScale = 0.94f;
public float selectAnimTime = 0.10f;
public float enterAnimTime = 0.22f;
// 0=TR, 1=EN, 2=ES, 3=DE, 4=FR, 5=PT
private string langCode; // "tr","en"...
private int langIndex; // 05
private class AnalogyQ
{
// data[language, field] -> 0:A 1:B 2:C 3:COR 4:W1 5:W2 6:W3
public string[,] data = new string[6, 7];
}
private List<AnalogyQ> questions = new List<AnalogyQ>();
private int correctIndex = -1;
private int selectedIndex = -1;
private bool locked = false;
private int lastQ = -1;
private int score = 0;
private int combo = 0;
private int correctCount = 0;
private int wrongCount = 0;
private float timeLeft = 60f;
private float nextTimer = 0f;
private string modKey = "Mod11";
readonly Color timerNormalColor = Color.white;
readonly Color timerWarnColor = new Color32(255, 80, 80, 255);
Vector3[] originalButtonScales;
Vector3[] originalButtonPositions;
Coroutine[] buttonScaleCoroutines;
Coroutine[] buttonEnterCoroutines;
Coroutine feedbackCo;
// ================================================================
void Start()
{
// Uses the same system as SentenceOrderGameScene
langCode = PlayerPrefs.GetString("QuestionLangCode", "en");
langIndex = GetLangIndex();
if (analogyFile == null)
{
Debug.LogError("AnalogyLogicGameScene: analogyFile is not assigned!");
if (questionText != null)
questionText.text = "TXT NOT FOUND!";
enabled = false;
return;
}
LoadTXT6Lang(analogyFile.text);
if (questions.Count == 0)
{
Debug.LogError("AnalogyLogicGameScene: TXT is empty or invalid!");
if (questionText != null)
questionText.text = "EMPTY FILE!";
enabled = false;
return;
}
if (answerButtons == null || answerButtons.Length < 4 ||
answerTexts == null || answerTexts.Length < 4)
{
Debug.LogError("AnalogyLogicGameScene: 4 answerButtons / answerTexts are required.");
enabled = false;
return;
}
CacheButtonData();
PrepareFeedbackText();
Shuffle(questions);
if (submitButton != null)
submitButton.onClick.AddListener(OnSubmit);
if (extraTimeButton != null)
extraTimeButton.onClick.AddListener(() => timeLeft += 5f);
if (extraHintButton != null)
extraHintButton.onClick.AddListener(OnHint);
if (extraSkipButton != null)
extraSkipButton.onClick.AddListener(NextQuestion);
if (backButton != null)
{
backButton.onClick.RemoveAllListeners();
backButton.onClick.AddListener(() => SceneManager.LoadScene(backSceneName));
}
if (scoreText != null)
scoreText.text = "0";
if (comboText != null)
comboText.text = "0x";
NextQuestion();
}
// ================================================================
void CacheButtonData()
{
if (answerButtons == null) return;
int len = answerButtons.Length;
originalButtonScales = new Vector3[len];
originalButtonPositions = new Vector3[len];
buttonScaleCoroutines = new Coroutine[len];
buttonEnterCoroutines = new Coroutine[len];
for (int i = 0; i < len; i++)
{
if (answerButtons[i] == null) continue;
originalButtonScales[i] = answerButtons[i].transform.localScale;
originalButtonPositions[i] = answerButtons[i].transform.localPosition;
answerButtons[i].transition = Selectable.Transition.None;
}
}
void PrepareFeedbackText()
{
if (feedbackText == null) return;
if (feedbackOnTop)
{
Vector3 pos = feedbackText.transform.localPosition;
pos.y = feedbackTopY;
feedbackText.transform.localPosition = pos;
}
feedbackText.alignment = TextAlignmentOptions.Center;
feedbackText.fontSize = Mathf.Max(feedbackText.fontSize, feedbackFontSize);
feedbackText.text = "";
Color c = feedbackText.color;
c.a = 1f;
feedbackText.color = c;
}
// ================================================================
// 6-LANGUAGE BLOCK TXT READER
// Each question: 6 lines (TR, EN, ES, DE, FR, PT)
// Line format: A,B,C,COR,W1,W2,W3
// ================================================================
void LoadTXT6Lang(string raw)
{
string[] lines = raw.Split('\n');
for (int i = 0; i < lines.Length;)
{
if (string.IsNullOrWhiteSpace(lines[i]))
{
i++;
continue;
}
if (i + 5 >= lines.Length)
break;
AnalogyQ q = new AnalogyQ();
bool validBlock = true;
for (int L = 0; L < 6; L++)
{
string line = lines[i + L].Trim('\r', '\n', ' ');
if (string.IsNullOrEmpty(line))
{
validBlock = false;
break;
}
string[] p = line.Split(',');
if (p.Length != 7)
{
Debug.LogWarning($"AnalogyLogicGameScene: line {i + L} does not contain 7 parts, block skipped.");
validBlock = false;
break;
}
for (int k = 0; k < 7; k++)
q.data[L, k] = p[k].Trim();
}
if (validBlock)
questions.Add(q);
i += 6;
}
}
// ================================================================
void Update()
{
if (!locked)
{
timeLeft -= Time.deltaTime;
if (timeLeft <= 0f)
{
timeLeft = 0f;
GameOver();
}
}
UpdateTimerUI();
if (locked && nextTimer > 0f)
{
nextTimer -= Time.deltaTime;
if (nextTimer <= 0f)
NextQuestion();
}
}
// ================================================================
void UpdateTimerUI()
{
if (timerText == null) return;
timerText.text = Mathf.Ceil(timeLeft).ToString();
if (timeLeft <= 10f)
{
timerText.color = FullAlpha(Color.Lerp(timerWarnColor, Color.white, Mathf.PingPong(Time.time * 3f, 1f)));
timerText.transform.localScale = Vector3.one * (1f + Mathf.Sin(Time.time * 10f) * 0.05f);
}
else
{
timerText.color = FullAlpha(timerNormalColor);
timerText.transform.localScale = Vector3.one;
}
}
// ================================================================
void NextQuestion()
{
locked = false;
selectedIndex = -1;
nextTimer = 0f;
if (selectedWordsText != null)
selectedWordsText.text = "";
if (feedbackText != null)
feedbackText.text = "";
for (int i = 0; i < answerButtons.Length; i++)
{
if (answerButtons[i] == null) continue;
StopButtonCoroutines(i);
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 = FullAlpha(normalColor);
}
if (questions.Count == 0)
{
GameOver();
return;
}
int id = Random.Range(0, questions.Count);
if (id == lastQ && questions.Count > 1)
id = (id + 1) % questions.Count;
lastQ = id;
AnalogyQ q = questions[id];
string A = q.data[langIndex, 0];
string B = q.data[langIndex, 1];
string C = q.data[langIndex, 2];
string COR = q.data[langIndex, 3];
string W1 = q.data[langIndex, 4];
string W2 = q.data[langIndex, 5];
string W3 = q.data[langIndex, 6];
if (questionText != null)
{
questionText.text = $"{A} : {B} = {C} : ?";
StartCoroutine(FadeInText(questionText));
}
List<string> opts = new List<string> { COR, W1, W2, W3 };
Shuffle(opts);
correctIndex = opts.IndexOf(COR);
for (int i = 0; i < 4; i++)
{
if (answerTexts[i] != null)
answerTexts[i].text = opts[i];
int x = i;
if (answerButtons[i] != null)
{
answerButtons[i].onClick.RemoveAllListeners();
answerButtons[i].onClick.AddListener(() => OnSelect(x));
buttonEnterCoroutines[i] = StartCoroutine(ButtonEnterAnim(answerButtons[i], i));
}
}
}
// ================================================================
void OnSelect(int id)
{
if (locked) return;
if (selectedIndex == id) return;
if (selectedIndex >= 0 && selectedIndex < answerButtons.Length && answerButtons[selectedIndex] != null)
{
if (answerButtons[selectedIndex].image != null)
answerButtons[selectedIndex].image.color = FullAlpha(normalColor);
StartScaleAnim(selectedIndex, originalButtonScales[selectedIndex]);
}
selectedIndex = id;
if (answerButtons[id] != null)
{
if (answerButtons[id].image != null)
answerButtons[id].image.color = FullAlpha(selectedColor);
StartScaleAnim(id, originalButtonScales[id] * selectedScale);
}
if (selectedWordsText != null && answerTexts[id] != null)
selectedWordsText.text = answerTexts[id].text;
}
// ================================================================
void OnSubmit()
{
if (locked) return;
if (selectedIndex == -1) return;
locked = true;
bool ok = (selectedIndex == correctIndex);
foreach (var b in answerButtons)
if (b != null) b.interactable = false;
if (ok)
{
correctCount++;
combo++;
score += 50 + combo * 10;
timeLeft += 2f;
if (answerButtons[selectedIndex] != null && answerButtons[selectedIndex].image != null)
answerButtons[selectedIndex].image.color = FullAlpha(correctColor);
StartCoroutine(CorrectPulse(answerButtons[selectedIndex], selectedIndex));
SetFeedback(combo >= 3 ? $"{Local("correct")} {combo}x COMBO!" : Local("correct"), correctColor);
if (comboText != null) StartCoroutine(ComboAnim(comboText));
}
else
{
wrongCount++;
combo = 0;
score -= 20;
if (score < 0) score = 0;
if (answerButtons[selectedIndex] != null && answerButtons[selectedIndex].image != null)
answerButtons[selectedIndex].image.color = FullAlpha(wrongColor);
StartCoroutine(ShakeButton(answerButtons[selectedIndex], selectedIndex));
if (correctIndex >= 0 && correctIndex < answerButtons.Length &&
answerButtons[correctIndex] != null && answerButtons[correctIndex].image != null)
{
answerButtons[correctIndex].image.color = FullAlpha(correctColor);
StartCoroutine(CorrectPulse(answerButtons[correctIndex], correctIndex));
}
SetFeedback(Local("wrong"), wrongColor);
}
if (scoreText != null)
{
scoreText.text = score.ToString();
StartCoroutine(ScorePopAnim(scoreText));
}
if (comboText != null)
comboText.text = combo + "x";
nextTimer = 1f;
}
// ================================================================
void OnHint()
{
if (locked) return;
if (lastQ < 0 || lastQ >= questions.Count) return;
string hint = questions[lastQ].data[langIndex, 3]; // correct answer
if (!string.IsNullOrEmpty(hint))
hint = hint.Length > 1 ? hint[0] + "..." : hint;
SetFeedback("Hint: " + hint, selectedColor);
}
// ================================================================
void SetFeedback(string msg, Color c)
{
if (feedbackText == null) return;
feedbackText.text = msg;
feedbackText.color = FullAlpha(c);
if (feedbackOnTop)
{
Vector3 pos = feedbackText.transform.localPosition;
pos.y = feedbackTopY;
feedbackText.transform.localPosition = pos;
}
if (feedbackCo != null) StopCoroutine(feedbackCo);
feedbackCo = StartCoroutine(FeedbackAnim(feedbackText));
}
// ================================================================
void GameOver()
{
// 🔥 Simple key that the Mod Select / Leaderboard screen can bind to directly
PlayerPrefs.SetInt("Mod11Skor", score);
PlayerPrefs.SetString("LastPlayedMod", modKey);
PlayerPrefs.SetInt(modKey + "_LastScore", score);
int best = PlayerPrefs.GetInt(modKey + "_MaxScore", 0);
if (score > best)
PlayerPrefs.SetInt(modKey + "_MaxScore", score);
PlayerPrefs.SetInt(modKey + "_Correct", correctCount);
PlayerPrefs.SetInt(modKey + "_Wrong", wrongCount);
PlayerPrefs.Save();
SceneManager.LoadScene("Mod11Resume");
}
// ================================================================
int GetLangIndex()
{
return langCode switch
{
"tr" => 1,
"en" => 0,
"es" => 2,
"de" => 3,
"fr" => 4,
"pt" => 5,
_ => 1 // default EN
};
}
// ================================================================
string Local(string key)
{
int L = GetLangIndex(); // Same as QuestionLangCode
switch (key)
{
case "correct":
return new[]
{
"Correct!", "Correct!", "Correct!", "Correct!", "Correct!", "Correct!"
}[L];
case "wrong":
return new[]
{
"Wrong!", "Wrong!", "Wrong!", "Wrong!", "Wrong!", "Wrong!"
}[L];
}
return key;
}
// ================================================================
void Shuffle<T>(IList<T> arr)
{
for (int i = 0; i < arr.Count; i++)
{
int r = Random.Range(i, arr.Count);
(arr[i], arr[r]) = (arr[r], arr[i]);
}
}
// ================== ANIMATION HELPERS ==================
void StartScaleAnim(int index, Vector3 targetScale)
{
if (index < 0 || index >= answerButtons.Length) return;
if (answerButtons[index] == null) return;
if (buttonScaleCoroutines[index] != null)
StopCoroutine(buttonScaleCoroutines[index]);
buttonScaleCoroutines[index] = StartCoroutine(ScaleButton(answerButtons[index], targetScale));
}
void StopButtonCoroutines(int index)
{
if (buttonScaleCoroutines != null && index < buttonScaleCoroutines.Length && buttonScaleCoroutines[index] != null)
{
StopCoroutine(buttonScaleCoroutines[index]);
buttonScaleCoroutines[index] = null;
}
if (buttonEnterCoroutines != null && index < buttonEnterCoroutines.Length && buttonEnterCoroutines[index] != null)
{
StopCoroutine(buttonEnterCoroutines[index]);
buttonEnterCoroutines[index] = null;
}
}
IEnumerator ScaleButton(Button btn, Vector3 targetScale)
{
if (btn == null) yield break;
Vector3 startScale = btn.transform.localScale;
float t = 0f;
while (t < 1f)
{
t += Time.deltaTime / Mathf.Max(0.01f, selectAnimTime);
btn.transform.localScale = Vector3.Lerp(startScale, targetScale, EaseOutQuad(t));
yield return null;
}
btn.transform.localScale = targetScale;
}
IEnumerator ButtonEnterAnim(Button btn, int delayIndex)
{
if (btn == null) yield break;
int idx = System.Array.IndexOf(answerButtons, btn);
if (idx < 0) yield break;
yield return new WaitForSeconds(delayIndex * 0.06f);
Vector3 targetPos = originalButtonPositions[idx];
Vector3 startPos = targetPos + Vector3.up * 35f;
Vector3 targetScale = originalButtonScales[idx];
Vector3 startScale = targetScale * 0.85f;
btn.transform.localPosition = startPos;
btn.transform.localScale = startScale;
float t = 0f;
while (t < 1f)
{
t += Time.deltaTime / Mathf.Max(0.01f, enterAnimTime);
float ease = EaseOutBack(t);
btn.transform.localPosition = Vector3.Lerp(startPos, targetPos, ease);
btn.transform.localScale = Vector3.Lerp(startScale, targetScale, ease);
yield return null;
}
btn.transform.localPosition = targetPos;
btn.transform.localScale = targetScale;
}
IEnumerator CorrectPulse(Button btn, int idx)
{
if (btn == null) yield break;
if (idx < 0 || idx >= originalButtonScales.Length) yield break;
Vector3 normal = originalButtonScales[idx];
Vector3 big = normal * 1.12f;
float t = 0f;
while (t < 1f)
{
t += Time.deltaTime / 0.12f;
btn.transform.localScale = Vector3.Lerp(normal, big, EaseOutQuad(t));
yield return null;
}
t = 0f;
while (t < 1f)
{
t += Time.deltaTime / 0.12f;
btn.transform.localScale = Vector3.Lerp(big, normal, EaseOutQuad(t));
yield return null;
}
btn.transform.localScale = normal;
}
IEnumerator ShakeButton(Button btn, int idx)
{
if (btn == null) yield break;
if (idx < 0 || idx >= originalButtonPositions.Length) yield break;
Vector3 origin = originalButtonPositions[idx];
float duration = 0.35f;
float magnitude = 12f;
float elapsed = 0f;
while (elapsed < duration)
{
float power = 1f - elapsed / duration;
float x = Random.Range(-1f, 1f) * magnitude * power;
btn.transform.localPosition = origin + new Vector3(x, 0f, 0f);
elapsed += Time.deltaTime;
yield return null;
}
btn.transform.localPosition = origin;
}
IEnumerator FeedbackAnim(TMP_Text txt)
{
if (txt == null) yield break;
Vector3 originalScale = Vector3.one;
Vector3 bigScale = originalScale * 1.18f;
Color c = FullAlpha(txt.color);
c.a = 0f;
txt.color = c;
Vector3 originalPos = txt.transform.localPosition;
Vector3 startPos = originalPos + Vector3.down * 18f;
txt.transform.localPosition = startPos;
float t = 0f;
while (t < 1f)
{
t += Time.deltaTime / 0.16f;
float ease = EaseOutBack(t);
txt.transform.localScale = Vector3.Lerp(originalScale, bigScale, ease);
txt.transform.localPosition = Vector3.Lerp(startPos, originalPos, ease);
c.a = Mathf.Clamp01(t);
txt.color = c;
yield return null;
}
c.a = 1f;
txt.color = c;
txt.transform.localPosition = originalPos;
t = 0f;
while (t < 1f)
{
t += Time.deltaTime / 0.12f;
txt.transform.localScale = Vector3.Lerp(bigScale, originalScale, EaseOutQuad(t));
yield return null;
}
txt.transform.localScale = originalScale;
feedbackCo = null;
}
IEnumerator ComboAnim(TMP_Text txt)
{
if (txt == null) yield break;
Vector3 original = Vector3.one;
Vector3 big = original * 1.22f;
Color baseColor = FullAlpha(txt.color);
Color highlight = new Color32(255, 220, 50, 255);
float t = 0f;
while (t < 1f)
{
t += Time.deltaTime / 0.12f;
txt.transform.localScale = Vector3.Lerp(original, big, EaseOutBack(t));
txt.color = FullAlpha(Color.Lerp(baseColor, highlight, t));
yield return null;
}
t = 0f;
while (t < 1f)
{
t += Time.deltaTime / 0.14f;
txt.transform.localScale = Vector3.Lerp(big, original, EaseOutQuad(t));
txt.color = FullAlpha(Color.Lerp(highlight, baseColor, t));
yield return null;
}
txt.transform.localScale = original;
txt.color = baseColor;
}
IEnumerator ScorePopAnim(TMP_Text txt)
{
if (txt == null) yield break;
Vector3 original = Vector3.one;
Vector3 big = original * 1.18f;
float t = 0f;
while (t < 1f)
{
t += Time.deltaTime / 0.10f;
txt.transform.localScale = Vector3.Lerp(original, big, EaseOutQuad(t));
yield return null;
}
t = 0f;
while (t < 1f)
{
t += Time.deltaTime / 0.12f;
txt.transform.localScale = Vector3.Lerp(big, original, EaseOutQuad(t));
yield return null;
}
txt.transform.localScale = original;
}
IEnumerator FadeInText(TMP_Text txt)
{
if (txt == null) yield break;
Color c = FullAlpha(txt.color);
c.a = 0f;
txt.color = c;
float t = 0f;
while (t < 1f)
{
t += Time.deltaTime / 0.18f;
c.a = EaseOutQuad(t);
txt.color = c;
yield return null;
}
c.a = 1f;
txt.color = c;
}
Color FullAlpha(Color c)
{
c.a = 1f;
return c;
}
float EaseOutBack(float t)
{
t = Mathf.Clamp01(t);
float c1 = 1.70158f;
float c3 = c1 + 1f;
return 1f + c3 * Mathf.Pow(t - 1f, 3f) + c1 * Mathf.Pow(t - 1f, 2f);
}
float EaseOutQuad(float t)
{
t = Mathf.Clamp01(t);
return 1f - (1f - t) * (1f - t);
}
}

View file

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: ff5c022bf505d8a4cbd87bc660103cf2

View file

@ -0,0 +1,154 @@
using System.Collections;
using TMPro;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
public class Mod11Resume : MonoBehaviour
{
[Header("UI TEXTS (ONLY NUMBERS)")]
public TMP_Text scoreText;
public TMP_Text maxScoreText;
public TMP_Text correctText;
public TMP_Text wrongText;
[Header("BUTTONS")]
public Button retryButton;
public Button exitButton;
[Header("AUDIO")]
public AudioSource sfx;
public AudioClip clickSound;
[Header("━━━ ANIMATION SETTINGS ━━━━━━━━━━━━━━━━━")]
public float countUpDuration = 0.8f;
public float popInDelay = 0.08f;
public float popInTime = 0.3f;
// 🔥 Bu modun özel PlayerPrefs anahtarı
private string modKey = "Mod11";
private int score;
private int maxScore;
private int correct;
private int wrong;
// ============================================================
void Start()
{
LoadResults();
PrepareTexts();
if (retryButton != null)
retryButton.onClick.AddListener(() => { PlaySFX(); Retry(); });
if (exitButton != null)
exitButton.onClick.AddListener(() => { PlaySFX(); ExitToMenu(); });
StartCoroutine(PlayRevealSequence());
}
// ============================================================
void LoadResults()
{
score = PlayerPrefs.GetInt(modKey + "_LastScore", 0);
maxScore = PlayerPrefs.GetInt(modKey + "_MaxScore", 0);
correct = PlayerPrefs.GetInt(modKey + "_Correct", 0);
wrong = PlayerPrefs.GetInt(modKey + "_Wrong", 0);
Debug.Log($"[MOD11 RESULT] Score={score} | Max={maxScore} | Correct={correct} | Wrong={wrong}");
}
// ============================================================
void PrepareTexts()
{
SetTextZero(scoreText);
SetTextZero(maxScoreText);
SetTextZero(correctText);
SetTextZero(wrongText);
}
void SetTextZero(TMP_Text txt)
{
if (txt == null) return;
txt.text = "0";
txt.transform.localScale = Vector3.zero;
}
// ============================================================
IEnumerator PlayRevealSequence()
{
yield return StartCoroutine(RevealStat(scoreText, score));
yield return new WaitForSeconds(popInDelay);
yield return StartCoroutine(RevealStat(maxScoreText, maxScore));
yield return new WaitForSeconds(popInDelay);
yield return StartCoroutine(RevealStat(correctText, correct));
yield return new WaitForSeconds(popInDelay);
yield return StartCoroutine(RevealStat(wrongText, wrong));
}
IEnumerator RevealStat(TMP_Text txt, int targetValue)
{
if (txt == null) yield break;
float t = 0f;
while (t < 1f)
{
t += Time.deltaTime / Mathf.Max(0.01f, popInTime);
txt.transform.localScale = Vector3.Lerp(Vector3.zero, Vector3.one, EaseOutBack(t));
if (targetValue == 0) txt.text = "0";
yield return null;
}
txt.transform.localScale = Vector3.one;
if (targetValue > 0)
{
float ct = 0f;
while (ct < 1f)
{
ct += Time.deltaTime / Mathf.Max(0.01f, countUpDuration);
txt.text = Mathf.RoundToInt(Mathf.Lerp(0, targetValue, EaseOutQuad(ct))).ToString();
yield return null;
}
}
txt.text = targetValue.ToString();
}
// ============================================================
void PlaySFX()
{
if (sfx && clickSound)
sfx.PlayOneShot(clickSound);
}
// ============================================================
void Retry()
{
// 🔥 Mod11 oyun sahnesine geri dön
SceneManager.LoadScene("Mod11");
}
// ============================================================
void ExitToMenu()
{
SceneManager.LoadScene("Anamen");
}
// ============================================================
float EaseOutBack(float t)
{
t = Mathf.Clamp01(t);
float c1 = 1.70158f, c3 = c1 + 1f;
return 1f + c3 * Mathf.Pow(t - 1f, 3f) + c1 * Mathf.Pow(t - 1f, 2f);
}
float EaseOutQuad(float t)
{
t = Mathf.Clamp01(t);
return 1f - (1f - t) * (1f - t);
}
}

View file

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 1781e8376e88df94187d95b3c65889d3

View file

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 792af35de8483a3408d24c7c79e3e76b
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,144 @@
using System.Collections;
using TMPro;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
public class Mod12Resume : MonoBehaviour
{
[Header("UI TEXTS (ONLY NUMBERS)")]
public TMP_Text scoreText;
public TMP_Text maxScoreText;
public TMP_Text correctText;
public TMP_Text wrongText;
[Header("BUTTONS")]
public Button retryButton;
public Button exitButton;
[Header("AUDIO")]
public AudioSource sfx;
public AudioClip clickSound;
[Header("━━━ ANIMATION SETTINGS ━━━━━━━━━━━━━━━━━")]
public float countUpDuration = 0.8f;
public float popInDelay = 0.08f;
public float popInTime = 0.3f;
private string modKey = "Mod12";
private int score;
private int maxScore;
private int correct;
private int wrong;
void Start()
{
LoadResults();
PrepareTexts();
if (retryButton)
retryButton.onClick.AddListener(() => { PlaySFX(); Retry(); });
if (exitButton)
exitButton.onClick.AddListener(() => { PlaySFX(); ExitToMenu(); });
StartCoroutine(PlayRevealSequence());
}
void LoadResults()
{
score = PlayerPrefs.GetInt(modKey + "_Score", 0);
maxScore = PlayerPrefs.GetInt(modKey + "_MaxScore", 0);
correct = PlayerPrefs.GetInt(modKey + "_Correct", 0);
wrong = PlayerPrefs.GetInt(modKey + "_Wrong", 0);
Debug.Log($"[MOD12 RESULT] Score={score} | Max={maxScore} | Correct={correct} | Wrong={wrong}");
}
void PrepareTexts()
{
SetTextZero(scoreText);
SetTextZero(maxScoreText);
SetTextZero(correctText);
SetTextZero(wrongText);
}
void SetTextZero(TMP_Text txt)
{
if (txt == null) return;
txt.text = "0";
txt.transform.localScale = Vector3.zero;
}
IEnumerator PlayRevealSequence()
{
yield return StartCoroutine(RevealStat(scoreText, score));
yield return new WaitForSeconds(popInDelay);
yield return StartCoroutine(RevealStat(maxScoreText, maxScore));
yield return new WaitForSeconds(popInDelay);
yield return StartCoroutine(RevealStat(correctText, correct));
yield return new WaitForSeconds(popInDelay);
yield return StartCoroutine(RevealStat(wrongText, wrong));
}
IEnumerator RevealStat(TMP_Text txt, int targetValue)
{
if (txt == null) yield break;
float t = 0f;
while (t < 1f)
{
t += Time.deltaTime / Mathf.Max(0.01f, popInTime);
txt.transform.localScale = Vector3.Lerp(Vector3.zero, Vector3.one, EaseOutBack(t));
if (targetValue == 0) txt.text = "0";
yield return null;
}
txt.transform.localScale = Vector3.one;
if (targetValue > 0)
{
float ct = 0f;
while (ct < 1f)
{
ct += Time.deltaTime / Mathf.Max(0.01f, countUpDuration);
txt.text = Mathf.RoundToInt(Mathf.Lerp(0, targetValue, EaseOutQuad(ct))).ToString();
yield return null;
}
}
txt.text = targetValue.ToString();
}
void PlaySFX()
{
if (sfx && clickSound)
sfx.PlayOneShot(clickSound);
}
void Retry()
{
SceneManager.LoadScene("Mod12");
}
void ExitToMenu()
{
SceneManager.LoadScene("Anamen");
}
float EaseOutBack(float t)
{
t = Mathf.Clamp01(t);
float c1 = 1.70158f, c3 = c1 + 1f;
return 1f + c3 * Mathf.Pow(t - 1f, 3f) + c1 * Mathf.Pow(t - 1f, 2f);
}
float EaseOutQuad(float t)
{
t = Mathf.Clamp01(t);
return 1f - (1f - t) * (1f - t);
}
}

View file

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 569283d0e752d7f4484717cd84e953c7

View file

@ -0,0 +1,662 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using TMPro;
using UnityEngine.SceneManagement;
public class Mod12_TrueFalseGame : MonoBehaviour
{
[Header("TXT FILE (TR,EN,ES,DE,FR,PT)")]
public TextAsset analogyFile; // TXT dosyasını sürükle-bırak
[System.Serializable]
public class WordPair
{
public string tr, en, es, de, fr, pt;
public WordPair(string tr, string en, string es, string de, string fr, string pt)
{
this.tr = tr;
this.en = en;
this.es = es;
this.de = de;
this.fr = fr;
this.pt = pt;
}
public string Get(string lang)
{
return lang switch
{
"tr" => tr,
"en" => en,
"es" => es,
"de" => de,
"fr" => fr,
"pt" => pt,
_ => en
};
}
}
// ================= UI =================
public TMP_Text wordText;
public TMP_Text feedbackText;
public TMP_Text scoreText;
public TMP_Text comboText;
public TMP_Text timerText;
public Button trueButton;
public Button falseButton;
public Button passButton;
[Header("━━━ BACK BUTTON ━━━━━━━━━━━━━━━━━━━━━━━━")]
public Button backButton;
public string backSceneName = "ModSec 12";
[Header("COLORS")]
public Color normalColor = new Color32(255, 255, 255, 40);
public Color selectedColor = new Color32(60, 120, 220, 255);
public Color correctColor = new Color32(0, 200, 0, 255);
public Color wrongColor = new Color32(200, 0, 0, 255);
[Header("━━━ FEEDBACK TEXT SETTINGS ━━━━━━━━━━━━━")]
public bool feedbackOnTop = true;
public float feedbackTopY = 400f;
public float feedbackFontSize = 72f;
[Header("━━━ ANIMATION SETTINGS ━━━━━━━━━━━━━━━━━")]
[Range(0.80f, 1f)] public float selectedScale = 0.94f;
public float selectAnimTime = 0.10f;
// ================= Logic =================
private List<WordPair> words = new List<WordPair>();
private bool correctPair;
private bool locked = false;
private float timeLeft = 60f;
private int score = 0;
private int combo = 0;
private int correctCount = 0;
private int wrongCount = 0;
string qLang;
string aLang;
string modKey = "Mod12";
readonly Color timerNormalColor = Color.white;
readonly Color timerWarnColor = new Color32(255, 80, 80, 255);
Vector3 trueOriginalScale = Vector3.one;
Vector3 falseOriginalScale = Vector3.one;
Vector3 trueOriginalPos;
Vector3 falseOriginalPos;
Coroutine trueScaleCo;
Coroutine falseScaleCo;
Coroutine feedbackCo;
Coroutine wordFadeCo;
// ============================================================
void Start()
{
qLang = PlayerPrefs.GetString("QuestionLangCode", "en");
aLang = PlayerPrefs.GetString("AnswerLangCode", "tr");
CacheButtonData();
PrepareFeedbackText();
LoadTXT();
trueButton.onClick.AddListener(() => Answer(true));
falseButton.onClick.AddListener(() => Answer(false));
passButton.onClick.AddListener(Pass);
if (backButton != null)
{
backButton.onClick.RemoveAllListeners();
backButton.onClick.AddListener(() => SceneManager.LoadScene(backSceneName));
}
UpdateScore();
UpdateCombo();
NextQuestion();
}
// ============================================================
void Update()
{
if (!locked)
{
timeLeft -= Time.deltaTime;
if (timeLeft <= 0) GameOver();
}
UpdateTimerUI();
}
// ============================================================
void CacheButtonData()
{
if (trueButton != null)
{
trueOriginalScale = trueButton.transform.localScale;
trueOriginalPos = trueButton.transform.localPosition;
trueButton.transition = Selectable.Transition.None;
}
if (falseButton != null)
{
falseOriginalScale = falseButton.transform.localScale;
falseOriginalPos = falseButton.transform.localPosition;
falseButton.transition = Selectable.Transition.None;
}
}
void PrepareFeedbackText()
{
if (feedbackText == null) return;
if (feedbackOnTop)
{
Vector3 pos = feedbackText.transform.localPosition;
pos.y = feedbackTopY;
feedbackText.transform.localPosition = pos;
}
feedbackText.alignment = TextAlignmentOptions.Center;
feedbackText.fontSize = Mathf.Max(feedbackText.fontSize, feedbackFontSize);
feedbackText.text = "";
Color c = feedbackText.color;
c.a = 1f;
feedbackText.color = c;
}
void UpdateTimerUI()
{
if (timerText == null) return;
timerText.text = Mathf.Ceil(timeLeft).ToString();
if (timeLeft <= 10f)
{
timerText.color = FullAlpha(Color.Lerp(timerWarnColor, Color.white, Mathf.PingPong(Time.time * 3f, 1f)));
timerText.transform.localScale = Vector3.one * (1f + Mathf.Sin(Time.time * 10f) * 0.05f);
}
else
{
timerText.color = FullAlpha(timerNormalColor);
timerText.transform.localScale = Vector3.one;
}
}
// ============================================================
void LoadTXT()
{
words.Clear();
if (analogyFile == null)
{
wordText.text = "TXT NOT FOUND!";
return;
}
string raw = analogyFile.text.Replace("\r", "");
string[] lines = raw.Split('\n');
foreach (string line in lines)
{
if (string.IsNullOrWhiteSpace(line)) continue;
string[] p = line.Split(',');
if (p.Length != 6)
{
Debug.LogError("HATALI SATIR → Format TR,EN,ES,DE,FR,PT olmalı: " + line);
continue;
}
words.Add(new WordPair(
p[0].Trim(), p[1].Trim(), p[2].Trim(),
p[3].Trim(), p[4].Trim(), p[5].Trim()
));
}
if (words.Count < 2)
{
wordText.text = "YETERSİZ KELİME!";
}
}
// ============================================================
void NextQuestion()
{
if (words.Count < 2) return;
locked = false;
if (feedbackText != null)
feedbackText.text = "";
ResetColors();
WordPair w1 = words[Random.Range(0, words.Count)];
WordPair w2 = w1;
// %50 doğru / %50 yanlış
correctPair = (Random.value > 0.5f);
if (!correctPair)
{
WordPair temp;
do temp = words[Random.Range(0, words.Count)];
while (temp == w1);
w2 = temp;
}
// TEK TEXT EKLEME
wordText.text = $"{w1.Get(qLang)} = {w2.Get(aLang)}";
if (wordFadeCo != null) StopCoroutine(wordFadeCo);
wordFadeCo = StartCoroutine(FadeInText(wordText));
}
// ============================================================
void Answer(bool pickedTrue)
{
if (locked) return;
locked = true;
bool ok =
(pickedTrue && correctPair) ||
(!pickedTrue && !correctPair);
if (pickedTrue)
{
trueButton.image.color = FullAlpha(selectedColor);
StartScaleAnim(trueButton, ref trueScaleCo, trueOriginalScale * selectedScale);
}
else
{
falseButton.image.color = FullAlpha(selectedColor);
StartScaleAnim(falseButton, ref falseScaleCo, falseOriginalScale * selectedScale);
}
if (ok) Correct(pickedTrue);
else Wrong(pickedTrue);
Invoke(nameof(NextQuestion), 1f);
}
// ============================================================
void Correct(bool pickedTrue)
{
correctCount++;
combo++;
score += 50 + combo * 10;
timeLeft += 2f;
SetFeedback(combo >= 3 ? $"{Local("correct")} {combo}x COMBO!" : Local("correct"), correctColor);
Button btn = pickedTrue ? trueButton : falseButton;
Vector3 normalScale = pickedTrue ? trueOriginalScale : falseOriginalScale;
btn.image.color = FullAlpha(correctColor);
StartCoroutine(CorrectPulse(btn, normalScale));
if (comboText != null) StartCoroutine(ComboAnim(comboText));
if (scoreText != null) StartCoroutine(ScorePopAnim(scoreText));
UpdateScore();
UpdateCombo();
}
void Wrong(bool pickedTrue)
{
wrongCount++;
combo = 0;
score -= 20;
if (score < 0) score = 0;
SetFeedback(Local("wrong"), wrongColor);
Button btn = pickedTrue ? trueButton : falseButton;
Vector3 originalPos = pickedTrue ? trueOriginalPos : falseOriginalPos;
btn.image.color = FullAlpha(wrongColor);
StartCoroutine(ShakeButton(btn, originalPos));
UpdateScore();
UpdateCombo();
}
// ============================================================
void Pass()
{
if (locked) return;
combo = 0;
UpdateCombo();
NextQuestion();
}
void ResetColors()
{
if (trueScaleCo != null) { StopCoroutine(trueScaleCo); trueScaleCo = null; }
if (falseScaleCo != null) { StopCoroutine(falseScaleCo); falseScaleCo = null; }
trueButton.image.color = FullAlpha(normalColor);
falseButton.image.color = FullAlpha(normalColor);
trueButton.transform.localScale = trueOriginalScale;
falseButton.transform.localScale = falseOriginalScale;
trueButton.transform.localPosition = trueOriginalPos;
falseButton.transform.localPosition = falseOriginalPos;
}
void UpdateScore() => scoreText.text = score.ToString();
void UpdateCombo() => comboText.text = combo + "x";
// ============================================================
void GameOver()
{
// Son elde edilen skor
int lastScore = score;
// 🔥 Mod Select / Leaderboard ekranına direkt bağlanacak basit key
PlayerPrefs.SetInt("Mod12Skor", lastScore);
// Mevcut max skoru oku (yoksa 0)
int maxScore = PlayerPrefs.GetInt(modKey + "_MaxScore", 0);
// Eğer yeni skor daha yüksekse güncelle
if (lastScore > maxScore)
{
PlayerPrefs.SetInt(modKey + "_MaxScore", lastScore);
}
// Temel kayıtlar
PlayerPrefs.SetInt(modKey + "_Score", lastScore);
PlayerPrefs.SetInt(modKey + "_Correct", correctCount);
PlayerPrefs.SetInt(modKey + "_Wrong", wrongCount);
PlayerPrefs.Save();
// Resume sahnesine git
SceneManager.LoadScene("Mod12Resume");
}
// ============================================================
string Local(string key)
{
int L = PlayerPrefs.GetInt("AppLanguage", 1);
if (key == "correct")
return new[] { "Doğru!", "Correct!", "¡Correcto!", "Richtig!", "Correct!", "Correto!" }[L];
if (key == "wrong")
return new[] { "Yanlış!", "Wrong!", "¡Incorrecto!", "Falsch!", "Faux!", "Errado!" }[L];
return key;
}
// ================== ANIMATION HELPERS ==================
void SetFeedback(string msg, Color c)
{
if (feedbackText == null) return;
feedbackText.text = msg;
feedbackText.color = FullAlpha(c);
if (feedbackOnTop)
{
Vector3 pos = feedbackText.transform.localPosition;
pos.y = feedbackTopY;
feedbackText.transform.localPosition = pos;
}
if (feedbackCo != null) StopCoroutine(feedbackCo);
feedbackCo = StartCoroutine(FeedbackAnim(feedbackText));
}
void StartScaleAnim(Button btn, ref Coroutine co, Vector3 targetScale)
{
if (btn == null) return;
if (co != null) StopCoroutine(co);
co = StartCoroutine(ScaleButton(btn, targetScale));
}
IEnumerator ScaleButton(Button btn, Vector3 targetScale)
{
if (btn == null) yield break;
Vector3 startScale = btn.transform.localScale;
float t = 0f;
while (t < 1f)
{
t += Time.deltaTime / Mathf.Max(0.01f, selectAnimTime);
btn.transform.localScale = Vector3.Lerp(startScale, targetScale, EaseOutQuad(t));
yield return null;
}
btn.transform.localScale = targetScale;
}
IEnumerator CorrectPulse(Button btn, Vector3 normal)
{
if (btn == null) yield break;
Vector3 big = normal * 1.12f;
float t = 0f;
while (t < 1f)
{
t += Time.deltaTime / 0.12f;
btn.transform.localScale = Vector3.Lerp(normal, big, EaseOutQuad(t));
yield return null;
}
t = 0f;
while (t < 1f)
{
t += Time.deltaTime / 0.12f;
btn.transform.localScale = Vector3.Lerp(big, normal, EaseOutQuad(t));
yield return null;
}
btn.transform.localScale = normal;
}
IEnumerator ShakeButton(Button btn, Vector3 origin)
{
if (btn == null) yield break;
float duration = 0.35f;
float magnitude = 12f;
float elapsed = 0f;
while (elapsed < duration)
{
float power = 1f - elapsed / duration;
float x = Random.Range(-1f, 1f) * magnitude * power;
btn.transform.localPosition = origin + new Vector3(x, 0f, 0f);
elapsed += Time.deltaTime;
yield return null;
}
btn.transform.localPosition = origin;
}
IEnumerator FeedbackAnim(TMP_Text txt)
{
if (txt == null) yield break;
Vector3 originalScale = Vector3.one;
Vector3 bigScale = originalScale * 1.18f;
Color c = FullAlpha(txt.color);
c.a = 0f;
txt.color = c;
Vector3 originalPos = txt.transform.localPosition;
Vector3 startPos = originalPos + Vector3.down * 18f;
txt.transform.localPosition = startPos;
float t = 0f;
while (t < 1f)
{
t += Time.deltaTime / 0.16f;
float ease = EaseOutBack(t);
txt.transform.localScale = Vector3.Lerp(originalScale, bigScale, ease);
txt.transform.localPosition = Vector3.Lerp(startPos, originalPos, ease);
c.a = Mathf.Clamp01(t);
txt.color = c;
yield return null;
}
c.a = 1f;
txt.color = c;
txt.transform.localPosition = originalPos;
t = 0f;
while (t < 1f)
{
t += Time.deltaTime / 0.12f;
txt.transform.localScale = Vector3.Lerp(bigScale, originalScale, EaseOutQuad(t));
yield return null;
}
txt.transform.localScale = originalScale;
feedbackCo = null;
}
IEnumerator ComboAnim(TMP_Text txt)
{
if (txt == null) yield break;
Vector3 original = Vector3.one;
Vector3 big = original * 1.22f;
Color baseColor = FullAlpha(txt.color);
Color highlight = new Color32(255, 220, 50, 255);
float t = 0f;
while (t < 1f)
{
t += Time.deltaTime / 0.12f;
txt.transform.localScale = Vector3.Lerp(original, big, EaseOutBack(t));
txt.color = FullAlpha(Color.Lerp(baseColor, highlight, t));
yield return null;
}
t = 0f;
while (t < 1f)
{
t += Time.deltaTime / 0.14f;
txt.transform.localScale = Vector3.Lerp(big, original, EaseOutQuad(t));
txt.color = FullAlpha(Color.Lerp(highlight, baseColor, t));
yield return null;
}
txt.transform.localScale = original;
txt.color = baseColor;
}
IEnumerator ScorePopAnim(TMP_Text txt)
{
if (txt == null) yield break;
Vector3 original = Vector3.one;
Vector3 big = original * 1.18f;
float t = 0f;
while (t < 1f)
{
t += Time.deltaTime / 0.10f;
txt.transform.localScale = Vector3.Lerp(original, big, EaseOutQuad(t));
yield return null;
}
t = 0f;
while (t < 1f)
{
t += Time.deltaTime / 0.12f;
txt.transform.localScale = Vector3.Lerp(big, original, EaseOutQuad(t));
yield return null;
}
txt.transform.localScale = original;
}
IEnumerator FadeInText(TMP_Text txt)
{
if (txt == null) yield break;
Color c = FullAlpha(txt.color);
c.a = 0f;
txt.color = c;
float t = 0f;
while (t < 1f)
{
t += Time.deltaTime / 0.18f;
c.a = EaseOutQuad(t);
txt.color = c;
yield return null;
}
c.a = 1f;
txt.color = c;
wordFadeCo = null;
}
Color FullAlpha(Color c)
{
c.a = 1f;
return c;
}
float EaseOutBack(float t)
{
t = Mathf.Clamp01(t);
float c1 = 1.70158f;
float c3 = c1 + 1f;
return 1f + c3 * Mathf.Pow(t - 1f, 3f) + c1 * Mathf.Pow(t - 1f, 2f);
}
float EaseOutQuad(float t)
{
t = Mathf.Clamp01(t);
return 1f - (1f - t) * (1f - t);
}
}

View file

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 59d2c4636dd071b498167e354fc0b612

View file

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 0b4d822743fa66c4a8c54880728ec78c
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,164 @@
using System.Collections;
using TMPro;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
public class Mod7Resume : MonoBehaviour
{
[Header("UI TEXTS (ONLY NUMBERS)")]
public TMP_Text scoreText;
public TMP_Text maxScoreText;
public TMP_Text correctText;
public TMP_Text wrongText;
[Header("BUTTONS")]
public Button retryButton;
public Button exitButton;
[Header("AUDIO")]
public AudioSource sfx;
public AudioClip clickSound;
[Header("━━━ ANIMATION SETTINGS ━━━━━━━━━━━━━━━━━")]
public float countUpDuration = 0.8f;
public float popInDelay = 0.08f;
public float popInTime = 0.3f;
private string modKey = "Mod7";
private int score;
private int maxScore;
private int correct;
private int wrong;
void Start()
{
LoadResults();
PrepareTexts();
if (retryButton != null)
retryButton.onClick.AddListener(() => { PlaySFX(); Retry(); });
if (exitButton != null)
exitButton.onClick.AddListener(() => { PlaySFX(); ExitToMenu(); });
StartCoroutine(PlayRevealSequence());
}
// ---------------------------------------------------------------
void LoadResults()
{
score = PlayerPrefs.GetInt(modKey + "_LastScore", 0);
maxScore = PlayerPrefs.GetInt(modKey + "_MaxScore", 0);
correct = PlayerPrefs.GetInt(modKey + "_Correct", 0);
wrong = PlayerPrefs.GetInt(modKey + "_Wrong", 0);
}
// ---------------------------------------------------------------
void PrepareTexts()
{
SetTextZero(scoreText);
SetTextZero(maxScoreText);
SetTextZero(correctText);
SetTextZero(wrongText);
}
void SetTextZero(TMP_Text txt)
{
if (txt == null) return;
txt.text = "0";
txt.transform.localScale = Vector3.zero;
}
// ---------------------------------------------------------------
IEnumerator PlayRevealSequence()
{
yield return StartCoroutine(RevealStat(scoreText, score));
yield return new WaitForSeconds(popInDelay);
yield return StartCoroutine(RevealStat(maxScoreText, maxScore));
yield return new WaitForSeconds(popInDelay);
yield return StartCoroutine(RevealStat(correctText, correct));
yield return new WaitForSeconds(popInDelay);
yield return StartCoroutine(RevealStat(wrongText, wrong));
}
IEnumerator RevealStat(TMP_Text txt, int targetValue)
{
if (txt == null) yield break;
// pop-in scale
Vector3 normal = Vector3.one;
float t = 0f;
while (t < 1f)
{
t += Time.deltaTime / Mathf.Max(0.01f, popInTime);
txt.transform.localScale = Vector3.Lerp(Vector3.zero, normal, EaseOutBack(t));
if (targetValue == 0)
txt.text = "0";
yield return null;
}
txt.transform.localScale = normal;
// count-up
if (targetValue > 0)
{
float ct = 0f;
while (ct < 1f)
{
ct += Time.deltaTime / Mathf.Max(0.01f, countUpDuration);
int shown = Mathf.RoundToInt(Mathf.Lerp(0, targetValue, EaseOutQuad(ct)));
txt.text = shown.ToString();
yield return null;
}
}
txt.text = targetValue.ToString();
}
// ---------------------------------------------------------------
void PlaySFX()
{
if (sfx && clickSound)
sfx.PlayOneShot(clickSound);
}
// ---------------------------------------------------------------
void Retry()
{
// 🔥 Mod 7 oyun sahnesine dön
SceneManager.LoadScene("Mod7");
}
// ---------------------------------------------------------------
void ExitToMenu()
{
SceneManager.LoadScene("Anamen");
}
// ---------------------------------------------------------------
float EaseOutBack(float t)
{
t = Mathf.Clamp01(t);
float c1 = 1.70158f;
float c3 = c1 + 1f;
return 1f + c3 * Mathf.Pow(t - 1f, 3f) + c1 * Mathf.Pow(t - 1f, 2f);
}
float EaseOutQuad(float t)
{
t = Mathf.Clamp01(t);
return 1f - (1f - t) * (1f - t);
}
}

View file

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 56be283e892927547817c76f96c0329e

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: e08b0cfd78da3f94b9cd70dfecc1eca4

View file

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 3d888a15222d70a4ab1849caa1545618
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,126 @@
using System.Collections;
using UnityEngine;
using UnityEngine.UI;
using TMPro;
using UnityEngine.SceneManagement;
public class Mod9Resume : MonoBehaviour
{
[Header("UI TEXTS")]
public TMP_Text scoreText;
public TMP_Text maxScoreText;
public TMP_Text correctText;
public TMP_Text wrongText;
[Header("BUTTONS")]
public Button retryButton;
public Button exitButton;
[Header("AUDIO")]
public AudioSource sfx;
public AudioClip clickSound;
[Header("━━━ ANIMATION SETTINGS ━━━━━━━━━━━━━━━━━")]
public float countUpDuration = 0.8f;
public float popInDelay = 0.08f;
public float popInTime = 0.3f;
private string modKey = "Mod9_Synonym";
int score, maxScore, correct, wrong;
void Start()
{
LoadResults();
PrepareTexts();
retryButton.onClick.AddListener(() => { PlaySFX(); SceneManager.LoadScene("Mod9"); });
exitButton.onClick.AddListener(() => { PlaySFX(); SceneManager.LoadScene("Anamen"); });
StartCoroutine(PlayRevealSequence());
}
void LoadResults()
{
score = PlayerPrefs.GetInt(modKey + "_LastScore", 0);
maxScore = PlayerPrefs.GetInt(modKey + "_MaxScore", 0);
correct = PlayerPrefs.GetInt(modKey + "_Correct", 0);
wrong = PlayerPrefs.GetInt(modKey + "_Wrong", 0);
}
void PrepareTexts()
{
SetTextZero(scoreText);
SetTextZero(maxScoreText);
SetTextZero(correctText);
SetTextZero(wrongText);
}
void SetTextZero(TMP_Text txt)
{
if (txt == null) return;
txt.text = "0";
txt.transform.localScale = Vector3.zero;
}
IEnumerator PlayRevealSequence()
{
yield return StartCoroutine(RevealStat(scoreText, score));
yield return new WaitForSeconds(popInDelay);
yield return StartCoroutine(RevealStat(maxScoreText, maxScore));
yield return new WaitForSeconds(popInDelay);
yield return StartCoroutine(RevealStat(correctText, correct));
yield return new WaitForSeconds(popInDelay);
yield return StartCoroutine(RevealStat(wrongText, wrong));
}
IEnumerator RevealStat(TMP_Text txt, int targetValue)
{
if (txt == null) yield break;
float t = 0f;
while (t < 1f)
{
t += Time.deltaTime / Mathf.Max(0.01f, popInTime);
txt.transform.localScale = Vector3.Lerp(Vector3.zero, Vector3.one, EaseOutBack(t));
if (targetValue == 0) txt.text = "0";
yield return null;
}
txt.transform.localScale = Vector3.one;
if (targetValue > 0)
{
float ct = 0f;
while (ct < 1f)
{
ct += Time.deltaTime / Mathf.Max(0.01f, countUpDuration);
txt.text = Mathf.RoundToInt(Mathf.Lerp(0, targetValue, EaseOutQuad(ct))).ToString();
yield return null;
}
}
txt.text = targetValue.ToString();
}
void PlaySFX()
{
if (sfx && clickSound)
sfx.PlayOneShot(clickSound);
}
float EaseOutBack(float t)
{
t = Mathf.Clamp01(t);
float c1 = 1.70158f, c3 = c1 + 1f;
return 1f + c3 * Mathf.Pow(t - 1f, 3f) + c1 * Mathf.Pow(t - 1f, 2f);
}
float EaseOutQuad(float t)
{
t = Mathf.Clamp01(t);
return 1f - (1f - t) * (1f - t);
}
}

View file

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 6f34180d9fade5c4fa76a9c5939efad7

View file

@ -0,0 +1,844 @@
using UnityEngine;
using UnityEngine.UI;
using TMPro;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine.SceneManagement;
public class WordMatchMod9 : MonoBehaviour
{
[Header("UI - QUESTIONS (LEFT)")]
[SerializeField] private Button[] questionButtons;
[SerializeField] private TMP_Text[] questionTexts;
[Header("UI - ANSWERS (RIGHT)")]
[SerializeField] private Button[] answerButtons;
[SerializeField] private TMP_Text[] answerTexts;
[Header("UI - OTHER")]
[SerializeField] private Button submitButton;
[SerializeField] private TMP_Text scoreText;
[SerializeField] private TMP_Text comboText;
[SerializeField] private TMP_Text timeText;
[SerializeField] private TMP_Text feedbackText;
[Header("━━━ BACK BUTTON ━━━━━━━━━━━━━━━━━━━━━━━━")]
public Button backButton;
public string backSceneName = "ModSec 9";
[Header("WORD DATA")]
[SerializeField] private TextAsset synonymFile;
[Header("COLORS")]
public Color baseColor = new Color32(230, 230, 230, 255);
public Color[] pairColors = new Color[]
{
new Color32(120,180,255,255),
new Color32(255,200,120,255),
new Color32(160,255,160,255),
new Color32(255,150,150,255),
new Color32(210,150,255,255),
};
public Color correctColor = new Color32(0, 160, 0, 255);
public Color wrongColor = new Color32(200, 0, 0, 255);
[Header("━━━ FEEDBACK TEXT SETTINGS ━━━━━━━━━━━━━")]
public bool feedbackOnTop = true;
public float feedbackTopY = 400f;
public float feedbackFontSize = 72f;
[Header("━━━ ANIMATION SETTINGS ━━━━━━━━━━━━━━━━━")]
[Range(0.80f, 1f)] public float selectedScale = 0.94f;
public float selectAnimTime = 0.10f;
public float enterAnimTime = 0.22f;
Dictionary<string, string> activeMap = new Dictionary<string, string>();
int[] questionToAnswer = new int[5];
int[] questionColorIdx = new int[5];
int[] answerColorIdx = new int[5];
int selectedQuestion = -1;
float timeLeft = 90f;
bool isTimeUp = false;
bool isRoundProcessing = false;
int score = 0;
int combo = 0;
int correctCount = 0;
int wrongCount = 0;
List<KeyValuePair<string, string>> selectedPairs = new List<KeyValuePair<string, string>>();
string modKey = "Mod9_Synonym";
private string qLang;
readonly Color timerNormalColor = Color.white;
readonly Color timerWarnColor = new Color32(255, 80, 80, 255);
Vector3[] questionOriginalScales;
Vector3[] answerOriginalScales;
Vector3[] questionOriginalPositions;
Vector3[] answerOriginalPositions;
Coroutine[] questionScaleCo;
Coroutine[] answerScaleCo;
Coroutine[] questionEnterCo;
Coroutine[] answerEnterCo;
Coroutine feedbackCo;
// ---------------------------------------------------------
void Start()
{
qLang = PlayerPrefs.GetString("QuestionLangCode", "en");
LoadSynonymFile();
CacheButtonData();
PrepareFeedbackText();
if (submitButton != null)
{
submitButton.onClick.RemoveAllListeners();
submitButton.onClick.AddListener(OnSubmit);
}
if (backButton != null)
{
backButton.onClick.RemoveAllListeners();
backButton.onClick.AddListener(() => SceneManager.LoadScene(backSceneName));
}
ResetMaps();
LoadRound();
scoreText.text = score.ToString();
comboText.text = combo + "x";
timeLeft = 90f;
isTimeUp = false;
}
// ---------------------------------------------------------
void Update()
{
if (isTimeUp)
{
UpdateTimerUI();
return;
}
timeLeft -= Time.deltaTime;
if (timeLeft < 0f) timeLeft = 0f;
UpdateTimerUI();
if (timeLeft <= 0f)
{
isTimeUp = true;
ProcessSubmit(true);
StartCoroutine(GoResume());
}
}
// ---------------------------------------------------------
void UpdateTimerUI()
{
if (timeText == null) return;
timeText.text = Mathf.CeilToInt(timeLeft).ToString();
if (timeLeft <= 10f)
{
timeText.color = FullAlpha(Color.Lerp(timerWarnColor, Color.white, Mathf.PingPong(Time.time * 3f, 1f)));
timeText.transform.localScale = Vector3.one * (1f + Mathf.Sin(Time.time * 10f) * 0.05f);
}
else
{
timeText.color = FullAlpha(timerNormalColor);
timeText.transform.localScale = Vector3.one;
}
}
// ---------------------------------------------------------
void LoadSynonymFile()
{
activeMap.Clear();
if (synonymFile == null)
{
Debug.LogError("Mod9: synonymFile atanmadı!");
return;
}
string[] lines = synonymFile.text.Split('\n');
int li = LangIndex(qLang);
for (int i = 0; i + 1 < lines.Length; i += 2)
{
string A = lines[i].Trim();
string B = lines[i + 1].Trim();
if (string.IsNullOrWhiteSpace(A) || string.IsNullOrWhiteSpace(B)) continue;
if (!A.Contains(",") || !B.Contains(",")) continue;
string[] wA = A.Split(',');
string[] wB = B.Split(',');
if (wA.Length < 6 || wB.Length < 6) continue;
string q = wA[li].Trim();
string a = wB[li].Trim();
if (!activeMap.ContainsKey(q))
activeMap.Add(q, a);
}
}
int LangIndex(string c)
{
switch (c)
{
case "tr": return 0;
case "en": return 1;
case "es": return 2;
case "de": return 3;
case "fr": return 4;
case "pt": return 5;
}
return 1;
}
// ---------------------------------------------------------
void CacheButtonData()
{
int n = questionButtons.Length;
questionOriginalScales = new Vector3[n];
answerOriginalScales = new Vector3[n];
questionOriginalPositions = new Vector3[n];
answerOriginalPositions = new Vector3[n];
questionScaleCo = new Coroutine[n];
answerScaleCo = new Coroutine[n];
questionEnterCo = new Coroutine[n];
answerEnterCo = new Coroutine[n];
for (int i = 0; i < n; i++)
{
if (questionButtons[i] != null)
{
questionOriginalScales[i] = questionButtons[i].transform.localScale;
questionOriginalPositions[i] = questionButtons[i].transform.localPosition;
questionButtons[i].transition = Selectable.Transition.None;
}
if (answerButtons[i] != null)
{
answerOriginalScales[i] = answerButtons[i].transform.localScale;
answerOriginalPositions[i] = answerButtons[i].transform.localPosition;
answerButtons[i].transition = Selectable.Transition.None;
}
}
}
void PrepareFeedbackText()
{
if (feedbackText == null) return;
if (feedbackOnTop)
{
Vector3 pos = feedbackText.transform.localPosition;
pos.y = feedbackTopY;
feedbackText.transform.localPosition = pos;
}
feedbackText.alignment = TextAlignmentOptions.Center;
feedbackText.fontSize = Mathf.Max(feedbackText.fontSize, feedbackFontSize);
feedbackText.text = "";
Color c = feedbackText.color;
c.a = 1f;
feedbackText.color = c;
}
// ---------------------------------------------------------
void LoadRound()
{
ResetVisuals();
ResetMaps();
isRoundProcessing = false;
var all = activeMap.ToList();
Shuffle(all);
selectedPairs = all.Take(5).ToList();
for (int i = 0; i < 5; i++)
{
questionTexts[i].text = selectedPairs[i].Key;
int id = i;
questionButtons[i].onClick.RemoveAllListeners();
questionButtons[i].onClick.AddListener(() => SelectQuestion(id));
}
List<string> answers = selectedPairs.Select(p => p.Value).ToList();
Shuffle(answers);
for (int i = 0; i < 5; i++)
{
answerTexts[i].text = answers[i];
int id = i;
answerButtons[i].onClick.RemoveAllListeners();
answerButtons[i].onClick.AddListener(() => SelectAnswer(id));
}
for (int i = 0; i < 5; i++)
{
if (questionEnterCo[i] != null) StopCoroutine(questionEnterCo[i]);
questionEnterCo[i] = StartCoroutine(ButtonEnterAnim(questionButtons[i], questionOriginalScales[i], questionOriginalPositions[i], i, -1));
if (answerEnterCo[i] != null) StopCoroutine(answerEnterCo[i]);
answerEnterCo[i] = StartCoroutine(ButtonEnterAnim(answerButtons[i], answerOriginalScales[i], answerOriginalPositions[i], i, 1));
if (questionTexts[i] != null) StartCoroutine(FadeInText(questionTexts[i]));
if (answerTexts[i] != null) StartCoroutine(FadeInText(answerTexts[i]));
}
}
// ---------------------------------------------------------
void ResetVisuals()
{
for (int i = 0; i < 5; i++)
{
StopButtonAnims(i);
questionButtons[i].image.color = FullAlpha(baseColor);
answerButtons[i].image.color = FullAlpha(baseColor);
questionButtons[i].transform.localScale = questionOriginalScales[i];
answerButtons[i].transform.localScale = answerOriginalScales[i];
questionButtons[i].transform.localPosition = questionOriginalPositions[i];
answerButtons[i].transform.localPosition = answerOriginalPositions[i];
}
if (feedbackText != null) feedbackText.text = "";
}
void StopButtonAnims(int i)
{
if (questionScaleCo[i] != null) { StopCoroutine(questionScaleCo[i]); questionScaleCo[i] = null; }
if (answerScaleCo[i] != null) { StopCoroutine(answerScaleCo[i]); answerScaleCo[i] = null; }
if (questionEnterCo[i] != null) { StopCoroutine(questionEnterCo[i]); questionEnterCo[i] = null; }
if (answerEnterCo[i] != null) { StopCoroutine(answerEnterCo[i]); answerEnterCo[i] = null; }
}
void ResetMaps()
{
for (int i = 0; i < 5; i++)
{
questionToAnswer[i] = -1;
questionColorIdx[i] = -1;
answerColorIdx[i] = -1;
}
}
// ---------------------------------------------------------
void SelectQuestion(int q)
{
if (isRoundProcessing || isTimeUp) return;
selectedQuestion = q;
StartScaleAnim(questionButtons, questionScaleCo, questionOriginalScales, q, questionOriginalScales[q] * selectedScale);
}
void SelectAnswer(int a)
{
if (isRoundProcessing || isTimeUp) return;
if (selectedQuestion == -1) return;
int prevQuestion = selectedQuestion;
if (questionToAnswer[selectedQuestion] == a)
{
questionToAnswer[selectedQuestion] = -1;
questionColorIdx[selectedQuestion] = -1;
answerColorIdx[a] = -1;
RefreshColors();
selectedQuestion = -1;
ResetScaleAnim(questionButtons, questionScaleCo, questionOriginalScales, prevQuestion);
ResetScaleAnim(answerButtons, answerScaleCo, answerOriginalScales, a);
return;
}
for (int i = 0; i < 5; i++)
{
if (questionToAnswer[i] == a && i != selectedQuestion)
{
questionToAnswer[i] = -1;
questionColorIdx[i] = -1;
ResetScaleAnim(questionButtons, questionScaleCo, questionOriginalScales, i);
}
}
int oldA = questionToAnswer[selectedQuestion];
if (oldA != -1)
{
answerColorIdx[oldA] = -1;
ResetScaleAnim(answerButtons, answerScaleCo, answerOriginalScales, oldA);
}
questionToAnswer[selectedQuestion] = a;
int c = selectedQuestion % pairColors.Length;
questionColorIdx[selectedQuestion] = c;
answerColorIdx[a] = c;
RefreshColors();
StartCoroutine(PairPulse(prevQuestion, a));
ResetScaleAnim(questionButtons, questionScaleCo, questionOriginalScales, prevQuestion);
selectedQuestion = -1;
}
void RefreshColors()
{
for (int i = 0; i < 5; i++)
{
questionButtons[i].image.color =
questionColorIdx[i] == -1 ? FullAlpha(baseColor) : FullAlpha(pairColors[questionColorIdx[i]]);
answerButtons[i].image.color =
answerColorIdx[i] == -1 ? FullAlpha(baseColor) : FullAlpha(pairColors[answerColorIdx[i]]);
}
}
// ---------------------------------------------------------
void OnSubmit()
{
if (isRoundProcessing || isTimeUp) return;
ProcessSubmit(false);
}
void ProcessSubmit(bool fromTimeout)
{
isRoundProcessing = true;
int roundCorrect = 0;
for (int q = 0; q < 5; q++)
{
int a = questionToAnswer[q];
if (a == -1)
{
questionButtons[q].image.color = FullAlpha(wrongColor);
StartCoroutine(ShakeButton(questionButtons[q], questionOriginalPositions[q]));
wrongCount++;
continue;
}
string qWord = questionTexts[q].text;
string correctA = activeMap[qWord];
string chosenA = answerTexts[a].text;
if (chosenA == correctA)
{
roundCorrect++;
correctCount++;
questionButtons[q].image.color = FullAlpha(correctColor);
answerButtons[a].image.color = FullAlpha(correctColor);
StartCoroutine(CorrectPulse(questionButtons[q], questionOriginalScales[q]));
StartCoroutine(CorrectPulse(answerButtons[a], answerOriginalScales[a]));
}
else
{
wrongCount++;
questionButtons[q].image.color = FullAlpha(wrongColor);
answerButtons[a].image.color = FullAlpha(wrongColor);
StartCoroutine(ShakeButton(questionButtons[q], questionOriginalPositions[q]));
StartCoroutine(ShakeButton(answerButtons[a], answerOriginalPositions[a]));
}
}
int gained = roundCorrect * 20;
score += gained;
Color feedbackColor;
if (roundCorrect == 5)
{
combo++;
feedbackText.text = combo >= 2 ? $"PERFECT! {combo}x COMBO!" : "PERFECT!";
feedbackColor = correctColor;
}
else if (roundCorrect > 0)
{
combo = 0;
feedbackText.text = "+" + gained + " Points";
feedbackColor = correctColor;
}
else
{
combo = 0;
feedbackText.text = "Try Again!";
feedbackColor = wrongColor;
}
feedbackText.color = FullAlpha(feedbackColor);
if (feedbackOnTop)
{
Vector3 pos = feedbackText.transform.localPosition;
pos.y = feedbackTopY;
feedbackText.transform.localPosition = pos;
}
if (feedbackCo != null) StopCoroutine(feedbackCo);
feedbackCo = StartCoroutine(FeedbackAnim(feedbackText));
scoreText.text = score.ToString();
comboText.text = combo + "x";
if (scoreText != null) StartCoroutine(ScorePopAnim(scoreText));
if (combo > 0 && comboText != null) StartCoroutine(ComboAnim(comboText));
SaveProgress();
if (!fromTimeout)
StartCoroutine(NextRound());
}
// ---------------------------------------------------------
void SaveProgress()
{
// 🔥 Mod Select / Leaderboard ekranına direkt bağlanacak basit key
PlayerPrefs.SetInt("Mod9Skor", score);
PlayerPrefs.SetInt(modKey + "_LastScore", score);
int best = PlayerPrefs.GetInt(modKey + "_MaxScore", 0);
if (score > best)
PlayerPrefs.SetInt(modKey + "_MaxScore", score);
PlayerPrefs.SetInt(modKey + "_Correct", correctCount);
PlayerPrefs.SetInt(modKey + "_Wrong", wrongCount);
PlayerPrefs.Save();
}
IEnumerator NextRound()
{
yield return new WaitForSeconds(0.8f);
LoadRound();
}
IEnumerator GoResume()
{
yield return new WaitForSeconds(1f);
SceneManager.LoadScene("Mod9Resume");
}
void Shuffle<T>(List<T> list)
{
for (int i = list.Count - 1; i > 0; i--)
{
int j = Random.Range(0, i + 1);
(list[i], list[j]) = (list[j], list[i]);
}
}
// ================== ANIMATION HELPERS ==================
void StartScaleAnim(Button[] buttons, Coroutine[] coArr, Vector3[] originalScales, int idx, Vector3 targetScale)
{
if (idx < 0 || idx >= buttons.Length || buttons[idx] == null) return;
if (coArr[idx] != null) StopCoroutine(coArr[idx]);
coArr[idx] = StartCoroutine(ScaleButton(buttons[idx], targetScale, idx, coArr));
}
void ResetScaleAnim(Button[] buttons, Coroutine[] coArr, Vector3[] originalScales, int idx)
{
if (idx < 0 || idx >= buttons.Length || buttons[idx] == null) return;
StartScaleAnim(buttons, coArr, originalScales, idx, originalScales[idx]);
}
IEnumerator ScaleButton(Button btn, Vector3 targetScale, int idx, Coroutine[] coArr)
{
if (btn == null) yield break;
Vector3 startScale = btn.transform.localScale;
float t = 0f;
while (t < 1f)
{
t += Time.deltaTime / Mathf.Max(0.01f, selectAnimTime);
btn.transform.localScale = Vector3.Lerp(startScale, targetScale, EaseOutQuad(t));
yield return null;
}
btn.transform.localScale = targetScale;
coArr[idx] = null;
}
IEnumerator ButtonEnterAnim(Button btn, Vector3 targetScale, Vector3 targetPos, int delayIndex, int sideSign)
{
if (btn == null) yield break;
yield return new WaitForSeconds(delayIndex * 0.05f);
Vector3 startPos = targetPos + new Vector3(sideSign * 40f, 0f, 0f);
Vector3 startScale = targetScale * 0.85f;
btn.transform.localPosition = startPos;
btn.transform.localScale = startScale;
float t = 0f;
while (t < 1f)
{
t += Time.deltaTime / Mathf.Max(0.01f, enterAnimTime);
float ease = EaseOutBack(t);
btn.transform.localPosition = Vector3.Lerp(startPos, targetPos, ease);
btn.transform.localScale = Vector3.Lerp(startScale, targetScale, ease);
yield return null;
}
btn.transform.localPosition = targetPos;
btn.transform.localScale = targetScale;
}
IEnumerator PairPulse(int questionIdx, int answerIdx)
{
if (questionIdx >= 0 && questionIdx < questionButtons.Length)
yield return StartCoroutine(QuickPulse(questionButtons[questionIdx].transform, questionOriginalScales[questionIdx]));
if (answerIdx >= 0 && answerIdx < answerButtons.Length)
yield return StartCoroutine(QuickPulse(answerButtons[answerIdx].transform, answerOriginalScales[answerIdx]));
}
IEnumerator QuickPulse(Transform tr, Vector3 normal)
{
if (tr == null) yield break;
Vector3 big = normal * 1.08f;
float t = 0f;
while (t < 1f)
{
t += Time.deltaTime / 0.08f;
tr.localScale = Vector3.Lerp(normal, big, EaseOutQuad(t));
yield return null;
}
t = 0f;
while (t < 1f)
{
t += Time.deltaTime / 0.08f;
tr.localScale = Vector3.Lerp(big, normal, EaseOutQuad(t));
yield return null;
}
tr.localScale = normal;
}
IEnumerator CorrectPulse(Button btn, Vector3 normal)
{
if (btn == null) yield break;
Vector3 big = normal * 1.12f;
float t = 0f;
while (t < 1f)
{
t += Time.deltaTime / 0.12f;
btn.transform.localScale = Vector3.Lerp(normal, big, EaseOutQuad(t));
yield return null;
}
t = 0f;
while (t < 1f)
{
t += Time.deltaTime / 0.12f;
btn.transform.localScale = Vector3.Lerp(big, normal, EaseOutQuad(t));
yield return null;
}
btn.transform.localScale = normal;
}
IEnumerator ShakeButton(Button btn, Vector3 origin)
{
if (btn == null) yield break;
float duration = 0.35f, magnitude = 12f, elapsed = 0f;
while (elapsed < duration)
{
float power = 1f - elapsed / duration;
float x = Random.Range(-1f, 1f) * magnitude * power;
btn.transform.localPosition = origin + new Vector3(x, 0f, 0f);
elapsed += Time.deltaTime;
yield return null;
}
btn.transform.localPosition = origin;
}
IEnumerator FeedbackAnim(TMP_Text txt)
{
if (txt == null) yield break;
Vector3 originalScale = Vector3.one;
Vector3 bigScale = originalScale * 1.18f;
Color c = FullAlpha(txt.color);
c.a = 0f;
txt.color = c;
Vector3 originalPos = txt.transform.localPosition;
Vector3 startPos = originalPos + Vector3.down * 18f;
txt.transform.localPosition = startPos;
float t = 0f;
while (t < 1f)
{
t += Time.deltaTime / 0.16f;
float ease = EaseOutBack(t);
txt.transform.localScale = Vector3.Lerp(originalScale, bigScale, ease);
txt.transform.localPosition = Vector3.Lerp(startPos, originalPos, ease);
c.a = Mathf.Clamp01(t);
txt.color = c;
yield return null;
}
c.a = 1f;
txt.color = c;
txt.transform.localPosition = originalPos;
t = 0f;
while (t < 1f)
{
t += Time.deltaTime / 0.12f;
txt.transform.localScale = Vector3.Lerp(bigScale, originalScale, EaseOutQuad(t));
yield return null;
}
txt.transform.localScale = originalScale;
feedbackCo = null;
}
IEnumerator ComboAnim(TMP_Text txt)
{
if (txt == null) yield break;
Vector3 original = Vector3.one;
Vector3 big = original * 1.22f;
Color baseC = FullAlpha(txt.color);
Color highlight = new Color32(255, 220, 50, 255);
float t = 0f;
while (t < 1f)
{
t += Time.deltaTime / 0.12f;
txt.transform.localScale = Vector3.Lerp(original, big, EaseOutBack(t));
txt.color = FullAlpha(Color.Lerp(baseC, highlight, t));
yield return null;
}
t = 0f;
while (t < 1f)
{
t += Time.deltaTime / 0.14f;
txt.transform.localScale = Vector3.Lerp(big, original, EaseOutQuad(t));
txt.color = FullAlpha(Color.Lerp(highlight, baseC, t));
yield return null;
}
txt.transform.localScale = original;
txt.color = baseC;
}
IEnumerator ScorePopAnim(TMP_Text txt)
{
if (txt == null) yield break;
Vector3 original = Vector3.one;
Vector3 big = original * 1.18f;
float t = 0f;
while (t < 1f)
{
t += Time.deltaTime / 0.10f;
txt.transform.localScale = Vector3.Lerp(original, big, EaseOutQuad(t));
yield return null;
}
t = 0f;
while (t < 1f)
{
t += Time.deltaTime / 0.12f;
txt.transform.localScale = Vector3.Lerp(big, original, EaseOutQuad(t));
yield return null;
}
txt.transform.localScale = original;
}
IEnumerator FadeInText(TMP_Text txt)
{
if (txt == null) yield break;
Color c = FullAlpha(txt.color);
c.a = 0f;
txt.color = c;
float t = 0f;
while (t < 1f)
{
t += Time.deltaTime / 0.18f;
c.a = EaseOutQuad(t);
txt.color = c;
yield return null;
}
c.a = 1f;
txt.color = c;
}
Color FullAlpha(Color c)
{
c.a = 1f;
return c;
}
float EaseOutBack(float t)
{
t = Mathf.Clamp01(t);
float c1 = 1.70158f, c3 = c1 + 1f;
return 1f + c3 * Mathf.Pow(t - 1f, 3f) + c1 * Mathf.Pow(t - 1f, 2f);
}
float EaseOutQuad(float t)
{
t = Mathf.Clamp01(t);
return 1f - (1f - t) * (1f - t);
}
}

View file

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: ebec7d06e1d313b43a00264a336593c9

8
Assets/Scripts/3.5.meta Normal file
View file

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: b91ba2dfe8cf306409c6ee34e3d2c255
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,71 @@
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
public class ModLeaderboard : MonoBehaviour
{
[Header("━━━ UI SLOTS (10 satır) ━━━━━━━━━━━━━━━")]
public TMP_Text[] rows;
[Header("━━━ BUTONLAR ━━━━━━━━━━━━━━━━━━━━━━━━━━")]
public Button mainMenuButton;
[Header("━━━ MOD AYARI ━━━━━━━━━━━━━━━━━━━━━━━━━")]
public string scoreKey = "GalaxyScore";
//
// Her mod için scoreKey değeri:
// ─────────────────────────────
// Galaxy Modu → "GalaxyScore"
// Time Modu → "TimeScore"
// Classic Modu → "ClassicScore"
// Challenge Modu → "ChallengeScore"
private readonly string[] botNames =
{
"ShadowWolf", "CrystalMind", "NightHunter",
"BlueVortex", "IronSoul", "PixelGhost",
"SilverClaw", "MegaCore", "NeonBlade", "DarkNova"
};
class LBEntry
{
public string name;
public int score;
public LBEntry(string n, int s) { name = n; score = s; }
}
void Start()
{
GenerateLeaderboard();
if (mainMenuButton != null)
mainMenuButton.onClick.AddListener(() =>
SceneManager.LoadScene("Anamen"));
}
void GenerateLeaderboard()
{
List<LBEntry> list = new List<LBEntry>();
int botLimit = Mathf.Min(rows.Length - 1, botNames.Length);
for (int i = 0; i < botLimit; i++)
list.Add(new LBEntry(botNames[i], Random.Range(3000, 12000)));
string highKey = scoreKey + "_High";
int lastScore = PlayerPrefs.GetInt(scoreKey, 0);
int highScore = PlayerPrefs.GetInt(highKey, 0);
if (lastScore > highScore)
{
highScore = lastScore;
PlayerPrefs.SetInt(highKey, highScore);
PlayerPrefs.Save();
}
list.Add(new LBEntry("YOU", highScore));
list.Sort((a, b) => b.score.CompareTo(a.score));
for (int i = 0; i < rows.Length; i++)
{
if (i < list.Count)
{
rows[i].text = list[i].name == "YOU"
? $"<color=#00FF00>{i + 1}. {list[i].name} - {list[i].score}</color>"
: $"{i + 1}. {list[i].name} - {list[i].score}";
}
else
{
rows[i].text = $"{i + 1}. ---";
}
}
}
}

View file

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 85e3141c0f135d94e9c099c2b7f5da74

View file

@ -0,0 +1,76 @@
using UnityEngine;
using UnityEngine.UI;
using TMPro;
using UnityEngine.SceneManagement;
using System.Collections.Generic;
public class ModSelectLanguageSettings : MonoBehaviour
{
[Header("━━━ DROPDOWNLAR ━━━━━━━━━━━━━━━━━━━━━━")]
public TMP_Dropdown questionDropdown;
public TMP_Dropdown answerDropdown;
[Header("━━━ BUTONLAR ━━━━━━━━━━━━━━━━━━━━━━━━━")]
public Button closeButton;
void Start()
{
PopulateDropdowns();
questionDropdown.value = PlayerPrefs.GetInt("QuestionLangID", 1);
answerDropdown.value = PlayerPrefs.GetInt("AnswerLangID", 0);
questionDropdown.RefreshShownValue();
answerDropdown.RefreshShownValue();
closeButton.onClick.AddListener(SaveAndClose);
}
void PopulateDropdowns()
{
List<string> languageNames = new List<string>
{
"Türkçe", // 0
"English", // 1
"Español", // 2
"Deutsch", // 3
"Français", // 4
"Português" // 5
};
questionDropdown.ClearOptions();
answerDropdown.ClearOptions();
questionDropdown.AddOptions(languageNames);
answerDropdown.AddOptions(languageNames);
}
void SaveAndClose()
{
int qID = questionDropdown.value;
int aID = answerDropdown.value;
PlayerPrefs.SetInt("QuestionLangID", qID);
PlayerPrefs.SetInt("AnswerLangID", aID);
PlayerPrefs.SetString("QuestionLangCode", ToCode(qID));
PlayerPrefs.SetString("AnswerLangCode", ToCode(aID));
PlayerPrefs.SetString("AppLanguage", ToCode(qID));
PlayerPrefs.Save();
gameObject.SetActive(false);
}
string ToCode(int id)
{
return id switch
{
0 => "tr",
1 => "en",
2 => "es",
3 => "de",
4 => "fr",
5 => "pt",
_ => "en"
};
}
}

View file

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 3eb2fcea3bc7c8b41b1842e752ce2168

View file

@ -0,0 +1,151 @@
using UnityEngine;
using TMPro;
using UnityEngine.UI;
using System.Collections.Generic;
using System;
public class ModWordListScreen : MonoBehaviour
{
[Header("━━━ LEVEL TXT DOSYALARI (6 DİL) ━━━━━━━")]
public TextAsset[] levelFiles;
[Header("━━━ 20 KELİME SLOTU ━━━━━━━━━━━━━━━━━━━")]
public TMP_Text[] wordTexts;
[Header("━━━ SAYFA BİLGİSİ ━━━━━━━━━━━━━━━━━━━━━")]
public TMP_Text pageInfoText;
[Header("━━━ BUTONLAR ━━━━━━━━━━━━━━━━━━━━━━━━━━")]
public Button nextButton;
public Button closeButton;
[Header("━━━ AUDIO ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")]
public AudioSource audioSource;
public AudioClip clickSound;
private string questionLang;
private string answerLang;
private int currentLevelIndex = 0;
private int currentPageIndex = 0;
private int PAGE_SIZE;
private List<WordPair> words = new();
private int MaxPageCount => (words.Count == 0) ? 1 : (words.Count - 1) / PAGE_SIZE + 1;
// ============================================================
void Awake()
{
PAGE_SIZE = (wordTexts != null && wordTexts.Length > 0) ? wordTexts.Length : 20;
}
void Start()
{
nextButton.onClick.AddListener(() => { PlayClick(); NextPage(); });
closeButton.onClick.AddListener(() => { PlayClick(); gameObject.SetActive(false); });
}
void OnEnable()
{
if (PAGE_SIZE == 0) return;
questionLang = PlayerPrefs.GetString("QuestionLangCode", "en");
answerLang = PlayerPrefs.GetString("AnswerLangCode", "tr");
currentLevelIndex = 0;
currentPageIndex = 0;
LoadLevel(currentLevelIndex);
ShowPage();
}
// ============================================================
void PlayClick()
{
if (audioSource && clickSound)
audioSource.PlayOneShot(clickSound);
}
// ============================================================
void LoadLevel(int index)
{
words.Clear();
currentPageIndex = 0;
if (index < 0 || index >= levelFiles.Length)
{
currentLevelIndex = 0;
LoadLevel(0);
return;
}
TextAsset txt = levelFiles[index];
if (txt == null) return;
string[] lines = txt.text.Split(
new[] { '\n', '\r' },
StringSplitOptions.RemoveEmptyEntries
);
foreach (string raw in lines)
{
string[] p = raw.Trim().Split(',');
if (p.Length < 6) continue;
words.Add(new WordPair(
p[0].Trim(), p[1].Trim(),
p[2].Trim(), p[3].Trim(),
p[4].Trim(), p[5].Trim()
));
}
}
// ============================================================
void ShowPage()
{
for (int i = 0; i < wordTexts.Length; i++)
wordTexts[i].text = "";
int start = currentPageIndex * PAGE_SIZE;
for (int i = 0; i < PAGE_SIZE; i++)
{
int index = start + i;
if (index >= words.Count || i >= wordTexts.Length) break;
WordPair w = words[index];
wordTexts[i].text = $"{w.GetByCode(questionLang)} → {w.GetByCode(answerLang)}";
}
UpdatePageInfo();
}
void UpdatePageInfo()
{
pageInfoText.text = $"Page {currentPageIndex + 1}/{MaxPageCount}";
}
// ============================================================
void NextPage()
{
if (currentPageIndex < MaxPageCount - 1)
{
currentPageIndex++;
ShowPage();
return;
}
if (currentLevelIndex < levelFiles.Length - 1)
{
currentLevelIndex++;
LoadLevel(currentLevelIndex);
ShowPage();
return;
}
currentLevelIndex = 0;
LoadLevel(0);
ShowPage();
}
}

View file

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: d7d689475375cc646bbae90bac8ed87a

View file

@ -0,0 +1,41 @@
using UnityEngine;
public class MusicManager : MonoBehaviour
{
[Header("━━━ MÜZIKLER (25 MP3) ━━━━━━━━━━━━━━━━━")]
public AudioClip[] songs;
[Header("━━━ AUDIO SOURCE ━━━━━━━━━━━━━━━━━━━━━━")]
public AudioSource audioSource;
private int lastIndex = -1;
// ============================================================
void Start()
{
PlayRandom();
}
void Update()
{
if (!audioSource.isPlaying)
PlayRandom();
}
// ============================================================
void PlayRandom()
{
if (songs == null || songs.Length == 0) return;
int index;
do
{
index = Random.Range(0, songs.Length);
}
while (index == lastIndex && songs.Length > 1); // aynı şarkı üst üste gelmesin
lastIndex = index;
audioSource.clip = songs[index];
audioSource.Play();
}
}

View file

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 5ee7bf0e8dcf55d49b30097a95df3c81

View file

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: c7231500a58028042884bbf82d67a21d
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,202 @@
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
using TMPro;
[System.Serializable]
public class ModData
{
public Sprite modSprite;
public string sceneName;
}
public class ModSelectManager : MonoBehaviour
{
[Header("━━━ MODLAR ━━━━━━━━━━━━━━━━━━━━━━━━━━━━")]
public ModData[] mods;
[Header("━━━ KART BOYUTLARI ━━━━━━━━━━━━━━━━━━━━")]
public float cardWidth = 900f;
public float cardHeight = 500f;
public float spacing = 40f;
[Header("━━━ PLAY BUTTON ━━━━━━━━━━━━━━━━━━━━━━━")]
public string playButtonText = "PLAY";
public float playButtonWidth = 400f;
public float playButtonHeight = 100f;
void Start()
{
Canvas canvas = FindAnyObjectByType<Canvas>();
if (canvas == null)
{
GameObject canvasObj = new GameObject("Canvas");
canvas = canvasObj.AddComponent<Canvas>();
canvas.renderMode = RenderMode.ScreenSpaceOverlay;
CanvasScaler scaler = canvasObj.AddComponent<CanvasScaler>();
scaler.uiScaleMode = CanvasScaler.ScaleMode.ScaleWithScreenSize;
scaler.referenceResolution = new Vector2(1080, 1920);
scaler.screenMatchMode = CanvasScaler.ScreenMatchMode.MatchWidthOrHeight;
scaler.matchWidthOrHeight = 0.5f;
canvasObj.AddComponent<GraphicRaycaster>();
}
GameObject oldScroll = GameObject.Find("ModScrollView");
if (oldScroll != null)
Destroy(oldScroll);
GameObject scrollObj = new GameObject("ModScrollView");
scrollObj.transform.SetParent(canvas.transform, false);
RectTransform scrollRect = scrollObj.AddComponent<RectTransform>();
scrollRect.anchorMin = Vector2.zero;
scrollRect.anchorMax = Vector2.one;
scrollRect.offsetMin = Vector2.zero;
scrollRect.offsetMax = Vector2.zero;
ScrollRect scroll = scrollObj.AddComponent<ScrollRect>();
scroll.horizontal = false;
scroll.vertical = true;
scroll.movementType = ScrollRect.MovementType.Elastic;
scroll.elasticity = 0.12f;
scroll.inertia = true;
scroll.decelerationRate = 0.135f;
scroll.scrollSensitivity = 30f;
GameObject viewportObj = new GameObject("Viewport");
viewportObj.transform.SetParent(scrollObj.transform, false);
RectTransform viewportRect = viewportObj.AddComponent<RectTransform>();
viewportRect.anchorMin = Vector2.zero;
viewportRect.anchorMax = Vector2.one;
viewportRect.offsetMin = Vector2.zero;
viewportRect.offsetMax = Vector2.zero;
Image viewportImage = viewportObj.AddComponent<Image>();
viewportImage.color = new Color(0f, 0f, 0f, 0f);
Mask mask = viewportObj.AddComponent<Mask>();
mask.showMaskGraphic = false;
GameObject contentObj = new GameObject("Content");
contentObj.transform.SetParent(viewportObj.transform, false);
RectTransform contentRect = contentObj.AddComponent<RectTransform>();
contentRect.anchorMin = new Vector2(0f, 1f);
contentRect.anchorMax = new Vector2(1f, 1f);
contentRect.pivot = new Vector2(0.5f, 1f);
contentRect.anchoredPosition = Vector2.zero;
contentRect.sizeDelta = Vector2.zero;
VerticalLayoutGroup vlg = contentObj.AddComponent<VerticalLayoutGroup>();
vlg.spacing = spacing;
vlg.padding = new RectOffset(50, 50, 50, 50);
vlg.childAlignment = TextAnchor.UpperCenter;
vlg.childControlWidth = false;
vlg.childControlHeight = false;
vlg.childForceExpandWidth = false;
vlg.childForceExpandHeight = false;
ContentSizeFitter csf = contentObj.AddComponent<ContentSizeFitter>();
csf.verticalFit = ContentSizeFitter.FitMode.PreferredSize;
csf.horizontalFit = ContentSizeFitter.FitMode.Unconstrained;
scroll.viewport = viewportRect;
scroll.content = contentRect;
if (mods == null || mods.Length == 0)
{
Debug.LogWarning("ModSelectManager: mods listesi boş.");
return;
}
foreach (ModData mod in mods)
{
if (mod == null)
continue;
GameObject card = new GameObject("ModCard");
card.transform.SetParent(contentObj.transform, false);
RectTransform cardRect = card.AddComponent<RectTransform>();
cardRect.sizeDelta = new Vector2(cardWidth, cardHeight);
LayoutElement cardLayout = card.AddComponent<LayoutElement>();
cardLayout.preferredWidth = cardWidth;
cardLayout.preferredHeight = cardHeight;
cardLayout.minWidth = cardWidth;
cardLayout.minHeight = cardHeight;
cardLayout.flexibleWidth = 0f;
cardLayout.flexibleHeight = 0f;
Image cardImg = card.AddComponent<Image>();
cardImg.color = new Color(0.1f, 0.1f, 0.2f, 1f);
GameObject imgObj = new GameObject("ModImage");
imgObj.transform.SetParent(card.transform, false);
RectTransform imgRect = imgObj.AddComponent<RectTransform>();
imgRect.anchorMin = Vector2.zero;
imgRect.anchorMax = Vector2.one;
imgRect.offsetMin = new Vector2(0f, 120f);
imgRect.offsetMax = Vector2.zero;
Image modImg = imgObj.AddComponent<Image>();
if (mod.modSprite != null)
modImg.sprite = mod.modSprite;
modImg.preserveAspect = true;
modImg.raycastTarget = false;
GameObject btnObj = new GameObject("PlayButton");
btnObj.transform.SetParent(card.transform, false);
RectTransform btnRect = btnObj.AddComponent<RectTransform>();
btnRect.anchorMin = new Vector2(0.5f, 0f);
btnRect.anchorMax = new Vector2(0.5f, 0f);
btnRect.pivot = new Vector2(0.5f, 0f);
btnRect.sizeDelta = new Vector2(playButtonWidth, playButtonHeight);
btnRect.anchoredPosition = new Vector2(0f, 10f);
Image btnImg = btnObj.AddComponent<Image>();
btnImg.color = new Color(0.1f, 0.7f, 0.2f, 1f);
Button btn = btnObj.AddComponent<Button>();
GameObject txtObj = new GameObject("Text");
txtObj.transform.SetParent(btnObj.transform, false);
RectTransform txtRect = txtObj.AddComponent<RectTransform>();
txtRect.anchorMin = Vector2.zero;
txtRect.anchorMax = Vector2.one;
txtRect.offsetMin = Vector2.zero;
txtRect.offsetMax = Vector2.zero;
TextMeshProUGUI tmp = txtObj.AddComponent<TextMeshProUGUI>();
tmp.text = playButtonText;
tmp.fontSize = 50f;
tmp.alignment = TextAlignmentOptions.Center;
tmp.color = Color.white;
tmp.raycastTarget = false;
string sceneName = mod.sceneName;
btn.onClick.RemoveAllListeners();
btn.onClick.AddListener(() =>
{
if (string.IsNullOrWhiteSpace(sceneName))
{
Debug.LogWarning("ModSelectManager: sceneName boş.");
return;
}
SceneManager.LoadScene(sceneName);
});
}
}
}

View file

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: a2b4db01ffdbb4c418ce084b87659f0f

View file

@ -0,0 +1,19 @@
using UnityEngine;
public class SoundManager : MonoBehaviour
{
public static SoundManager instance;
public AudioSource audioSource;
public AudioClip clickSound;
void Awake()
{
instance = this;
}
public void PlayClick()
{
if (audioSource && clickSound)
audioSource.PlayOneShot(clickSound);
}
}

View file

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 1a1f2461a1242e640a3493747a8569fe

8
Assets/Scripts/4.0.meta Normal file
View file

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 3eaa755588ef6dc4d866d6d46bd31fc1
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 0e64226fc93230e468c6e079da9aae49
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 61dd7d6ceab294248b449636b8a1782e

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 538fa4417c4f71a46ac17c5757fd58e0

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 50748c22127712a49a561ea211e5e37f

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: b3cc7e81eafd2c545b3e3bdf2caa5eae

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 7224becc3185c2c4082b7a3239f14a17

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: eb226f785cec9b14d981b272d70f9b04

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: fe8c1b46957e6224c932624f5702a716

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: a2a6355bbf47b3a4caca990aad5a9ada

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: d2ec54f76aab0954eafe3db5d61be279

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: f3452baaffc11c74aa6442f8fe9e9d46

File diff suppressed because it is too large Load diff

Some files were not shown because too many files have changed in this diff Show more