Ekosistem_Game/Assets/Script/ManagerKuis.cs

407 lines
14 KiB
C#

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<ManagerSuaraBermain>();
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);
}
}