using UnityEngine; using UnityEngine.UI; using System.Collections; using TMPro; using UnityEngine.SceneManagement; public class ManagerKuis : MonoBehaviour { [Header("--- PANEL NAVIGASI & POP UP ---")] public GameObject panelPilihLevel; public GameObject panelGamePilihan; public GameObject panelPopUpBenar; public GameObject popUpSalah; public static bool mauUlangKuis = false; // --- SATPAM SUARA (SINKRON DENGAN GAME LAIN) --- public static bool sudahPernahSapaKuis = false; [Header("--- KOLEKSI SUARA KUIS ---")] public AudioSource speakerGame; [Tooltip("Masukkan suara narator untuk menyapa pertama kali")] public AudioClip kasetSapaanAwal; [Tooltip("Masukkan 5 kaset suara soal sesuai urutan (0-4)")] public AudioClip[] kasetNaratorSoal; public AudioClip kasetBenar; public AudioClip kasetSalah; public AudioClip kasetPopUpHebat; public AudioClip kasetPanelHasil; public AudioClip kasetKlikTombol; public AudioClip kasetKalahWaktu; [Header("--- DAFTAR PANEL SOAL ---")] public GameObject[] daftarSoal; private int soalSekarang = 0; [Header("--- SISTEM SKOR KIRI ---")] public Image barSkor; public TextMeshProUGUI teksSkorKiri; public Image[] bintangSkorProgress; private int jumlahBenar = 0; [Header("--- PENGATURAN WAKTU ---")] public float waktuSisa = 60f; private float waktuAwal; private bool gameSelesai = false; public Image barWaktu; // --- BARU: KONTROL WAKTU --- private bool waktuBolehJalan = false; [Header("--- PANEL HASIL AKHIR & ANIMASI ---")] public GameObject panelHasil; public RectTransform kontenPanelHasil; public Image[] slotBintangPanel; public TextMeshProUGUI teksSkorAkhir; // --- BARU: FITUR ANTI-KLIK --- [Header("--- FITUR ANTI-KLIK ---")] public CanvasGroup groupKlikGame; // TARIK PANEL_GAMEPILIHAN KE SINI private bool sedangDiproses = false; // <--- VARIABEL BARU UNTUK KUNCI SPAM KLIK void Start() { // 1. Bersihkan total semua suara & coroutine masa lalu StopAllCoroutines(); if (speakerGame != null) speakerGame.Stop(); waktuAwal = waktuSisa; gameSelesai = false; waktuBolehJalan = false; // Awalnya waktu dihentikan dulu jumlahBenar = 0; soalSekarang = 0; sedangDiproses = false; // Buka gembok saat game baru mulai // Pastikan awal game gemboknya terbuka untuk jaga-jaga if (groupKlikGame != null) groupKlikGame.blocksRaycasts = true; // Sembunyikan semua soal di awal for (int i = 0; i < daftarSoal.Length; i++) { if (daftarSoal[i] != null) daftarSoal[i].SetActive(false); } // Munculkan soal pertama if (daftarSoal.Length > 0 && daftarSoal[0] != null) { daftarSoal[0].SetActive(true); } // LOGIKA SINKRON: Cek jika lagi mode ulangi if (mauUlangKuis) { if (panelPilihLevel != null) panelPilihLevel.SetActive(false); if (panelGamePilihan != null) panelGamePilihan.SetActive(true); mauUlangKuis = false; MulaiSuaraNaratorSatuPintu(); } // Reset Pop Up & Panel if (popUpSalah != null) popUpSalah.SetActive(false); if (panelPopUpBenar != null) panelPopUpBenar.SetActive(false); if (panelHasil != null) panelHasil.SetActive(false); // Reset UI Skor & Bintang if (barSkor != null) barSkor.fillAmount = 0; if (teksSkorKiri != null) teksSkorKiri.text = "0"; foreach (Image b in bintangSkorProgress) { if(b != null) b.color = Color.gray; } foreach (Image b in slotBintangPanel) { if(b != null) b.color = Color.gray; } // Reset Bar Waktu if (barWaktu != null) { barWaktu.fillAmount = 1; barWaktu.color = Color.white; } } // --- FUNGSI MASUK DARI PETA --- public void MasukGameDanNgomongKuis() { // ========================================================= // JURUS MUTLAK ANTI-NABRAK: TEMBAK LANGSUNG DARI KODE! // ========================================================= ManagerSuaraBermain satpamMenu = FindObjectOfType(); if (satpamMenu != null) { satpamMenu.HentikanPaksaSuara(); // Paksa diam detik ini juga! } if (panelPilihLevel != null) panelPilihLevel.SetActive(false); if (panelGamePilihan != null) panelGamePilihan.SetActive(true); MulaiSuaraNaratorSatuPintu(); } public void MulaiSuaraNaratorSatuPintu() { StopAllCoroutines(); if (speakerGame != null) { speakerGame.Stop(); StartCoroutine(JedaSuaraKuis()); } } IEnumerator JedaSuaraKuis() { // Kunci tombol pas narator ngomong if (groupKlikGame != null) groupKlikGame.blocksRaycasts = false; waktuBolehJalan = false; yield return new WaitForSeconds(0.2f); if (!sudahPernahSapaKuis) { if (kasetSapaanAwal != null) { speakerGame.PlayOneShot(kasetSapaanAwal); yield return new WaitForSeconds(kasetSapaanAwal.length + 0.3f); sudahPernahSapaKuis = true; } } // Buka gembok setelah narator beres if (groupKlikGame != null) groupKlikGame.blocksRaycasts = true; waktuBolehJalan = true; PutarSuaraNaratorSoal(soalSekarang); } // --- JURUS TIGA TOMBOL (BIAR MUNCUL DI LIST INSPECTOR) --- public void KlikPilihanA(AudioClip kaset) { ProsesKlikPilihan(kaset); } public void KlikPilihanB(AudioClip kaset) { ProsesKlikPilihan(kaset); } public void KlikPilihanC(AudioClip kaset) { ProsesKlikPilihan(kaset); } void ProsesKlikPilihan(AudioClip kaset) { if (gameSelesai) return; speakerGame.Stop(); // Hentikan narator soal if (speakerGame != null && kaset != null) speakerGame.PlayOneShot(kaset); } public void JawabanBenar() { // Cek gembok: Jika game selesai atau jawaban masih diproses, batalkan klik if (gameSelesai || sedangDiproses) return; sedangDiproses = true; // Langsung kunci! StartCoroutine(ProsesBenar()); } IEnumerator ProsesBenar() { yield return new WaitForSeconds(0.3f); if (speakerGame != null && kasetBenar != null) speakerGame.PlayOneShot(kasetBenar); jumlahBenar++; UpdateUISkorKiri(); StartCoroutine(TampilPopUpLanjutSoal()); } public void JawabanSalah() { // Cek gembok: Jika game selesai atau jawaban masih diproses, batalkan klik if (gameSelesai || sedangDiproses) return; sedangDiproses = true; // Langsung kunci! StartCoroutine(ProsesSalah()); } IEnumerator ProsesSalah() { yield return new WaitForSeconds(0.3f); if (speakerGame != null && kasetSalah != null) speakerGame.PlayOneShot(kasetSalah); if (popUpSalah != null) { popUpSalah.SetActive(true); StopCoroutine("HilangkanPopUpOtomatis"); StartCoroutine(HilangkanPopUpOtomatis()); } } // --- ANIMASI TOMBOL MEMBAL --- public void AnimasiTombolKlik(RectTransform tombolRect) { StartCoroutine(ProsesAnimasiTombol(tombolRect)); } IEnumerator ProsesAnimasiTombol(RectTransform target) { Vector3 skalaAwal = Vector3.one; Vector3 skalaKecil = Vector3.one * 0.85f; Vector3 skalaGede = Vector3.one * 1.15f; float t = 0; while(t < 1f){ t += Time.deltaTime * 15f; target.localScale = Vector3.Lerp(skalaAwal, skalaKecil, t); yield return null; } t = 0; while(t < 1f){ t += Time.deltaTime * 12f; target.localScale = Vector3.Lerp(skalaKecil, skalaGede, t); yield return null; } t = 0; while(t < 1f){ t += Time.deltaTime * 10f; target.localScale = Vector3.Lerp(skalaGede, skalaAwal, t); yield return null; } target.localScale = skalaAwal; } IEnumerator TampilPopUpLanjutSoal() { // Kunci pas pindah soal biar gak di spam klik if (groupKlikGame != null) groupKlikGame.blocksRaycasts = false; waktuBolehJalan = false; yield return new WaitForSeconds(0.4f); if (panelPopUpBenar != null) panelPopUpBenar.SetActive(true); if (speakerGame != null && kasetPopUpHebat != null) speakerGame.PlayOneShot(kasetPopUpHebat); yield return new WaitForSeconds(1.5f); if (panelPopUpBenar != null) panelPopUpBenar.SetActive(false); if (soalSekarang < daftarSoal.Length - 1) { if (daftarSoal[soalSekarang] != null) daftarSoal[soalSekarang].SetActive(false); soalSekarang++; if (daftarSoal[soalSekarang] != null) daftarSoal[soalSekarang].SetActive(true); // Buka gembok buat soal selanjutnya if (groupKlikGame != null) groupKlikGame.blocksRaycasts = true; waktuBolehJalan = true; sedangDiproses = false; // Buka gembok karena soal baru sudah muncul PutarSuaraNaratorSoal(soalSekarang); } else { MenangMain(); } } void PutarSuaraNaratorSoal(int index) { if (speakerGame != null && kasetNaratorSoal != null && index < kasetNaratorSoal.Length) { if (kasetNaratorSoal[index] != null) { speakerGame.Stop(); speakerGame.PlayOneShot(kasetNaratorSoal[index]); } } } void Update() { if (gameSelesai) return; // --- BARU: JIKA NARATOR BICARA / DIKUNCI, JANGAN JALAN WAKTUNYA --- if (!waktuBolehJalan) return; if (waktuSisa > 0) { waktuSisa -= Time.deltaTime; if (barWaktu != null) { barWaktu.fillAmount = waktuSisa / waktuAwal; if (waktuSisa <= 10f) barWaktu.color = Color.red; } } else { AkhiriGameWaktuHabis(); } } void UpdateUISkorKiri() { if (daftarSoal.Length == 0) return; float persentase = (float)jumlahBenar / daftarSoal.Length; if (barSkor != null) barSkor.fillAmount = persentase; if (teksSkorKiri != null) teksSkorKiri.text = Mathf.RoundToInt(persentase * 100f).ToString(); if (bintangSkorProgress.Length >= 3) { if (persentase >= 0.33f) bintangSkorProgress[0].color = Color.white; if (persentase >= 0.66f) bintangSkorProgress[1].color = Color.white; if (persentase >= 1.00f) bintangSkorProgress[2].color = Color.white; } } void AkhiriGameWaktuHabis() { if (gameSelesai) return; gameSelesai = true; waktuSisa = 0; if (barWaktu != null) barWaktu.fillAmount = 0; GagalMain(); } void MenangMain() { if (gameSelesai) return; gameSelesai = true; waktuBolehJalan = false; StartCoroutine(AnimasiPanelDanBintang(3, false)); } void GagalMain() { gameSelesai = true; waktuBolehJalan = false; float persentase = (float)jumlahBenar / daftarSoal.Length; int bintang = 0; if (persentase >= 1.00f) bintang = 3; else if (persentase >= 0.66f) bintang = 2; else if (persentase >= 0.33f) bintang = 1; StartCoroutine(AnimasiPanelDanBintang(bintang, true)); } IEnumerator AnimasiPanelDanBintang(int jumlahBintang, bool waktuHabis) { // --- BUKA KUNCI KLIK DISINI BIAR AMAN SAAT MUNCUL HASIL --- if (groupKlikGame != null) groupKlikGame.blocksRaycasts = true; if (kontenPanelHasil != null) { kontenPanelHasil.localScale = Vector3.zero; panelHasil.SetActive(true); panelHasil.transform.SetAsLastSibling(); float t = 0; while (t < 1f) { t += Time.deltaTime * 4f; float curve = Mathf.Sin(t * Mathf.PI * 0.7f) * 1.15f; kontenPanelHasil.localScale = Vector3.one * curve; yield return null; } kontenPanelHasil.localScale = Vector3.one; } if (teksSkorAkhir != null) teksSkorAkhir.text = teksSkorKiri.text; if (waktuHabis) { if (kasetKalahWaktu != null) speakerGame.PlayOneShot(kasetKalahWaktu); } else { if (kasetPanelHasil != null) speakerGame.PlayOneShot(kasetPanelHasil); } yield return new WaitForSeconds(0.3f); for (int i = 0; i < jumlahBintang; i++) { if (i < slotBintangPanel.Length && slotBintangPanel[i] != null) { if(kasetBenar != null) speakerGame.PlayOneShot(kasetBenar); slotBintangPanel[i].color = Color.white; float bT = 0; Vector3 startS = Vector3.one * 2f; while(bT < 1f){ bT += Time.deltaTime * 5f; slotBintangPanel[i].rectTransform.localScale = Vector3.Lerp(startS, Vector3.one, bT); yield return null; } yield return new WaitForSeconds(0.4f); } } } IEnumerator HilangkanPopUpOtomatis() { yield return new WaitForSeconds(1.5f); if (popUpSalah != null) popUpSalah.SetActive(false); sedangDiproses = false; // Buka gembok karena pop-up sudah hilang, pemain bisa klik lagi } public void TombolUlangi() { if (speakerGame != null && kasetKlikTombol != null) speakerGame.PlayOneShot(kasetKlikTombol); sudahPernahSapaKuis = false; mauUlangKuis = true; SceneManager.LoadScene(SceneManager.GetActiveScene().name); } public void TombolKeluar() { if (speakerGame != null && kasetKlikTombol != null) speakerGame.PlayOneShot(kasetKlikTombol); sudahPernahSapaKuis = false; mauUlangKuis = false; SceneManager.LoadScene(SceneManager.GetActiveScene().name); } }