using UnityEngine; using UnityEngine.UI; using System.Collections; using System.Collections.Generic; using TMPro; using UnityEngine.SceneManagement; public class GameManagerSusun : MonoBehaviour { public static GameManagerSusun instance; [Header("Sistem Data Soal")] public VegetableSusun[] listSoal; private int indexSoal = 0; [Header("Sistem Skor & Progress")] public Slider sliderSkor; public TextMeshProUGUI textSkor; public Material materialKartuAtas; public Image bintang1, bintang2, bintang3; public Sprite bintangNyala; private float skorSekarangVisual = 0; private int skorTarget = 0; [Header("Sistem Timer")] public TextMeshProUGUI textTimer; public float durasiMenit = 2f; private float waktuTersisa; private bool gameAktif = false; [Header("Area & Prefabs")] public Transform letterGrid; public Transform letterBank; public Image displaySayur; public GameObject slotPrefab; public GameObject kartuStatisPrefab; public GameObject kartuDragPrefab; [Header("Sistem Suara")] public AudioClip suaraBintang; [Header("UI PopUp & Board Hasil Akhir")] public GameObject popupWahKeren; public GameObject popupSalah; public GameObject panelBoardHasil; public GameObject latarHitam; public TextMeshProUGUI textNilaiAkhir; public Image hasilBintang1, hasilBintang2, hasilBintang3; [Header("Sistem Audio")] public AudioSource audioSource; public AudioClip sfxDropBenar; void Awake() { if (instance == null) instance = this; } void Start() { skorTarget = 0; skorSekarangVisual = 0; indexSoal = 0; waktuTersisa = durasiMenit * 60f; gameAktif = true; if(sliderSkor != null) { sliderSkor.maxValue = 100; sliderSkor.value = 0; } ResetPopups(); UpdateVisualSkor(); MuatSoal(); } void ResetPopups() { if(popupWahKeren != null) popupWahKeren.SetActive(false); if(popupSalah != null) popupSalah.SetActive(false); if(panelBoardHasil != null) panelBoardHasil.SetActive(false); if(latarHitam != null) latarHitam.SetActive(false); } void Update() { if (gameAktif && waktuTersisa > 0) { waktuTersisa -= Time.deltaTime; UpdateDisplayTimer(); } else if (gameAktif && waktuTersisa <= 0) { MunculkanBoardAkhir(); } if (sliderSkor != null && skorSekarangVisual < skorTarget) { skorSekarangVisual = Mathf.MoveTowards(skorSekarangVisual, skorTarget, 50f * Time.deltaTime); sliderSkor.value = skorSekarangVisual; CheckBintangLevel(skorSekarangVisual, bintang1, bintang2, bintang3); } } public void MuatSoal() { ResetPopups(); foreach (Transform child in letterGrid) Destroy(child.gameObject); foreach (Transform child in letterBank) Destroy(child.gameObject); if (indexSoal >= listSoal.Length) { MunculkanBoardAkhir(); return; } VegetableSusun data = listSoal[indexSoal]; displaySayur.sprite = data.gambarSayur; char[] hurufArray = data.namaSayur.ToUpper().ToCharArray(); List listHurufBank = new List(); for (int i = 0; i < hurufArray.Length; i++) { if (data.visibilityHuruf[i] == true) { GameObject kartu = Instantiate(kartuStatisPrefab, letterGrid); kartu.GetComponentInChildren().text = hurufArray[i].ToString(); } else { GameObject slot = Instantiate(slotPrefab, letterGrid); slot.GetComponent().jawabanBenar = hurufArray[i]; listHurufBank.Add(hurufArray[i]); } } if (!string.IsNullOrEmpty(data.hurufPengecoh)) { foreach (char p in data.hurufPengecoh.ToUpper().ToCharArray()) { listHurufBank.Add(p); } } for (int i = 0; i < listHurufBank.Count; i++) { char temp = listHurufBank[i]; int randomIndex = Random.Range(i, listHurufBank.Count); listHurufBank[i] = listHurufBank[randomIndex]; listHurufBank[randomIndex] = temp; } foreach (char h in listHurufBank) { GameObject kartuDrag = Instantiate(kartuDragPrefab, letterBank); kartuDrag.GetComponent().isiHuruf = h; kartuDrag.GetComponentInChildren().text = h.ToString(); } } public void CekJawaban() { if (audioSource != null && sfxDropBenar != null) audioSource.PlayOneShot(sfxDropBenar); bool semuaSlotSudahTerisi = true; SlotHuruf[] semuaSlot = letterGrid.GetComponentsInChildren(); foreach (SlotHuruf slot in semuaSlot) { if (!slot.sudahTerisi) { semuaSlotSudahTerisi = false; break; } } if (semuaSlotSudahTerisi) { // Ambil referensi soal SEKARANG sebelum index berubah VegetableSusun soalSekarang = listSoal[indexSoal]; StartCoroutine(UrutanMenangSoal(soalSekarang)); } } // Tambahkan parameter VegetableSusun agar VO tidak salah panggil IEnumerator UrutanMenangSoal(VegetableSusun data) { // 1. Efek Kartu Hijau (Blink) StartCoroutine(EfekKartuHijau()); yield return new WaitForSeconds(0.8f); // 2. Putar VO Nama Sayur if (audioSource != null && data.voSayur != null) { audioSource.PlayOneShot(data.voSayur); // Tunggu sampai VO benar-benar selesai yield return new WaitForSeconds(data.voSayur.length); } // 3. Jeda tambahan 1 detik yield return new WaitForSeconds(0.5f); // 4. Munculkan Pop Up Benar skorTarget += 10; UpdateVisualSkor(); if(popupWahKeren != null) popupWahKeren.SetActive(true); // 5. Jeda Pop Up muncul sebelum ganti soal yield return new WaitForSeconds(1f); indexSoal++; MuatSoal(); } // Fungsi-fungsi lainnya tetap sama... // (MunculkanWrong, EfekKartuHijau, dll) public void MunculkanWrong() { if(popupSalah != null) { popupSalah.SetActive(true); StopCoroutine("SembunyikanWrongTimer"); StartCoroutine(SembunyikanWrongTimer()); } } IEnumerator SembunyikanWrongTimer() { yield return new WaitForSeconds(1f); if(popupSalah != null) popupSalah.SetActive(false); } public void MunculkanBoardAkhir() { // 1. Cek pengaman agar tidak simpan berkali-kali if (!gameAktif) return; gameAktif = false; // --- PROSES SIMPAN DATA KE DATABASE JSON --- float durasiMain = 0; TimeTracker tt = FindObjectOfType(); if (tt != null) durasiMain = tt.GetDurasiBermain(); if (SaveSystem.instance != null) { // Index 3 adalah khusus untuk Game Susun Huruf SaveSystem.instance.SimpanHasilGame(3, skorTarget, durasiMain); } // -------------------------------------------- waktuTersisa = 0; textTimer.text = "00:00"; if(panelBoardHasil != null) { if(latarHitam != null) latarHitam.SetActive(true); panelBoardHasil.SetActive(true); StartCoroutine(AnimasiHasilAkhir()); } } IEnumerator AnimasiHasilAkhir() { float durasiAcak = 0.1f; float timerAcak = 0; // Ambil komponen AudioSource untuk memutar suara AudioSource audio = GetComponent(); // Efek angka acak sebelum skor asli muncul while (timerAcak < durasiAcak) { timerAcak += Time.deltaTime; int angkaTampil = Random.Range(0, skorTarget + 1); if(textNilaiAkhir != null) textNilaiAkhir.text = angkaTampil.ToString(); yield return new WaitForSeconds(0.05f); } if(textNilaiAkhir != null) textNilaiAkhir.text = skorTarget.ToString(); yield return new WaitForSeconds(0.3f); // --- PROSES MUNCUL BINTANG DENGAN SUARA --- // Bintang 1 (Skor minimal 40) if (skorTarget >= 40 && hasilBintang1 != null) { hasilBintang1.sprite = bintangNyala; // Mainkan Suara if(audio != null && suaraBintang != null) audio.PlayOneShot(suaraBintang); if(hasilBintang1.GetComponent()) hasilBintang1.GetComponent().enabled = true; yield return new WaitForSeconds(0.5f); // Jeda sebelum bintang berikutnya } // Bintang 2 (Skor minimal 80) if (skorTarget >= 80 && hasilBintang2 != null) { hasilBintang2.sprite = bintangNyala; // Mainkan Suara (Pitch dinaikkan dikit biar suaranya lebih tinggi/ceriam) if(audio != null && suaraBintang != null) { audio.pitch = 1.1f; audio.PlayOneShot(suaraBintang); } if(hasilBintang2.GetComponent()) hasilBintang2.GetComponent().enabled = true; yield return new WaitForSeconds(0.5f); } // Bintang 3 (Skor sempurna 100) if (skorTarget >= 100 && hasilBintang3 != null) { hasilBintang3.sprite = bintangNyala; // Mainkan Suara (Pitch dinaikkan lagi) if(audio != null && suaraBintang != null) { audio.pitch = 1.2f; audio.PlayOneShot(suaraBintang); } if(hasilBintang3.GetComponent()) hasilBintang3.GetComponent().enabled = true; // Kembalikan pitch ke normal setelah selesai if(audio != null) audio.pitch = 1f; } } void UpdateDisplayTimer() { float menit = Mathf.FloorToInt(waktuTersisa / 60); float detik = Mathf.FloorToInt(waktuTersisa % 60); textTimer.text = string.Format("{0:00}:{1:00}", menit, detik); } void UpdateVisualSkor() { if(textSkor != null) textSkor.text = skorTarget.ToString(); } void CheckBintangLevel(float skor, Image b1, Image b2, Image b3) { if (skor >= 40 && b1 != null) b1.sprite = bintangNyala; if (skor >= 80 && b2 != null) b2.sprite = bintangNyala; if (skor >= 100 && b3 != null) b3.sprite = bintangNyala; } IEnumerator EfekKartuHijau() { Image[] semuaGambar = letterGrid.GetComponentsInChildren(); foreach (Image img in semuaGambar) img.color = Color.green; yield return new WaitForSeconds(0.5f); foreach (Image img in semuaGambar) img.color = Color.white; } public void TombolReplay() { SceneManager.LoadScene(SceneManager.GetActiveScene().name); } public void TombolKembaliMenu() { SceneManager.LoadScene("MenuBermain"); } }