using UnityEngine; using UnityEngine.UI; using System.Collections; using UnityEngine.SceneManagement; using TMPro; public class GameManager : MonoBehaviour { [Header("--- PANEL NAVIGASI & POP UP ---")] public GameObject panelPilihLevel; public GameObject panelGameSortir; public GameObject panelPopUpBenar; public static bool mauUlangSortir = false; // --- BARU: SATPAM SUARA BIAR GAK NGOMONG TERUS TIAP RONDE --- public static bool sudahPernahSapaSortir = false; [Header("--- KOLEKSI SUARA SORTIR ---")] public AudioSource speakerGame; public AudioClip kasetNarator; public AudioClip kasetBenarMasuk; public AudioClip kasetSalahMasuk; public AudioClip kasetPopUpHebat; public AudioClip kasetPanelHasil; public AudioClip kasetKalahWaktu; public AudioClip kasetKlik; [Header("--- PENGATURAN WAKTU & TIMER ---")] public float waktuSisa = 120f; private float waktuAwal; private bool gameSelesai = false; public Image barWaktu; public RectTransform ikonJam; private float posisiAwalJamY; private float tinggiBarWaktu; // --- BARU: KONTROL WAKTU --- private bool waktuBolehJalan = false; [Header("--- PENGATURAN SKOR KIRI ---")] public Image barSkor; public Image[] bintangSkorProgress; public TextMeshProUGUI teksSkor; private int skorKeseluruhan = 0; private int totalSemuaHewanGame = 0; [Header("--- DAFTAR RONDE ---")] public GameObject[] daftarRonde; private int rondeSekarang = 0; private int hewanMasukRondeIni = 0; private int targetHewanRondeIni = 0; [Header("--- PANEL HASIL AKHIR & ANIMASI ---")] public GameObject panelHasil; public RectTransform kontenPanelHasil; public TextMeshProUGUI teksSkorAkhir; public Image[] slotBintangPanel; [Header("--- FITUR ANTI-KLIK ---")] public CanvasGroup groupKlikGame; // TARIK PANEL_GAMESORTIR KE SINI void Start() { // 1. BERSIHKAN TOTAL SEMUA SUARA SAAT SCENE BARU MULAI StopAllCoroutines(); if (speakerGame != null) speakerGame.Stop(); waktuAwal = waktuSisa; waktuBolehJalan = false; // Awalnya waktu dihentikan dulu if(panelHasil != null) panelHasil.SetActive(false); if(panelPopUpBenar != null) panelPopUpBenar.SetActive(false); foreach (Image bintang in slotBintangPanel) { if(bintang != null) bintang.color = Color.gray; } if (ikonJam != null && barWaktu != null) { posisiAwalJamY = ikonJam.anchoredPosition.y; tinggiBarWaktu = barWaktu.GetComponent().rect.height; } if (barSkor != null) barSkor.fillAmount = 0; if (teksSkor != null) teksSkor.text = "0"; foreach (Image bintang in bintangSkorProgress) { if(bintang != null) bintang.color = Color.gray; } HitungTotalSemuaHewan(); MulaiRonde(0); // 2. CEK APAKAH LAGI MODE ULANGI if (mauUlangSortir) { if (panelPilihLevel != null) panelPilihLevel.SetActive(false); if (panelGameSortir != null) panelGameSortir.SetActive(true); mauUlangSortir = false; // Trigger suara narator lewat fungsi pemicu tunggal MulaiSuaraNaratorSatuPintu(); } } // --- FUNGSI SATU PINTU UNTUK SUARA NARATOR --- public void MulaiSuaraNaratorSatuPintu() { // Pastikan tidak ada suara lain yang jalan sebelum narator mulai StopAllCoroutines(); if (speakerGame != null) { speakerGame.Stop(); StartCoroutine(LogikaTungguNarator()); } } IEnumerator LogikaTungguNarator() { // 1. Kunci klik (user gak bisa narik hewan atau klik tombol game) if (groupKlikGame != null) groupKlikGame.blocksRaycasts = false; waktuBolehJalan = false; yield return new WaitForSeconds(0.2f); if (!sudahPernahSapaSortir) { if (kasetNarator != null) { speakerGame.PlayOneShot(kasetNarator); // Tunggu sampai narator selesai bicara yield return new WaitForSeconds(kasetNarator.length); sudahPernahSapaSortir = true; } } // 2. Buka kunci klik dan jalankan waktu if (groupKlikGame != null) groupKlikGame.blocksRaycasts = true; waktuBolehJalan = true; } public void MasukGameDanNgomong() { // ========================================================= // 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 (panelGameSortir != null) panelGameSortir.SetActive(true); MulaiSuaraNaratorSatuPintu(); } void HitungTotalSemuaHewan() { totalSemuaHewanGame = 0; foreach (GameObject ronde in daftarRonde) { if (ronde != null) { DragHewan[] semuaHewan = ronde.GetComponentsInChildren(true); foreach (DragHewan h in semuaHewan) { if (h.asalEkosistem != JenisEkosistem.Pengecoh) totalSemuaHewanGame++; } } } } void Update() { if (gameSelesai) return; if (panelGameSortir != null && !panelGameSortir.activeSelf) return; // --- BARU: JIKA NARATOR BICARA / DIKUNCI, JANGAN JALAN WAKTUNYA --- if (!waktuBolehJalan) return; if (waktuSisa > 0) { waktuSisa -= Time.deltaTime; float rasioWaktu = waktuSisa / waktuAwal; if (barWaktu != null) { barWaktu.fillAmount = rasioWaktu; if (waktuSisa <= 10f) barWaktu.color = Color.red; else barWaktu.color = Color.white; } if (ikonJam != null) { float targetY = posisiAwalJamY - (tinggiBarWaktu * (1f - rasioWaktu)); ikonJam.anchoredPosition = Vector2.Lerp(ikonJam.anchoredPosition, new Vector2(ikonJam.anchoredPosition.x, targetY), Time.deltaTime * 5f); } } else { waktuSisa = 0; if (barWaktu != null) barWaktu.fillAmount = 0; AkhiriGame(true); } } public void JawabanSalah() { if (gameSelesai) return; if (speakerGame != null && kasetSalahMasuk != null) speakerGame.PlayOneShot(kasetSalahMasuk); } public void TambahSkor(AudioClip suaraEkosistem = null) { if (gameSelesai) return; if (speakerGame != null && kasetBenarMasuk != null) speakerGame.PlayOneShot(kasetBenarMasuk); if (speakerGame != null && suaraEkosistem != null) { StartCoroutine(JedaNarasiEkosistem(suaraEkosistem)); } hewanMasukRondeIni++; skorKeseluruhan++; float persentaseSkor = totalSemuaHewanGame > 0 ? (float)skorKeseluruhan / totalSemuaHewanGame : 0f; int skorTampil = Mathf.RoundToInt(persentaseSkor * 100f); if (teksSkor != null) teksSkor.text = skorTampil.ToString(); if (barSkor != null) barSkor.fillAmount = persentaseSkor; if (bintangSkorProgress.Length >= 3) { if (persentaseSkor >= 0.33f && bintangSkorProgress[0] != null) bintangSkorProgress[0].color = Color.white; if (persentaseSkor >= 0.66f && bintangSkorProgress[1] != null) bintangSkorProgress[1].color = Color.white; if (persentaseSkor >= 1.00f && bintangSkorProgress[2] != null) bintangSkorProgress[2].color = Color.white; } if (hewanMasukRondeIni >= targetHewanRondeIni) { DragHewan[] semuaHewanSisaDiLayar = FindObjectsOfType(); foreach (DragHewan hewan in semuaHewanSisaDiLayar) hewan.gameObject.SetActive(false); if(daftarRonde[rondeSekarang] != null) daftarRonde[rondeSekarang].SetActive(false); StartCoroutine(TampilPopUpLanjutRonde()); } } IEnumerator JedaNarasiEkosistem(AudioClip clip) { yield return new WaitForSeconds(0.4f); speakerGame.PlayOneShot(clip); } IEnumerator TampilPopUpLanjutRonde() { 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); rondeSekarang++; LanjutRondeBerikutnya(); } void MulaiRonde(int index) { if (index < daftarRonde.Length) { if (daftarRonde[index] != null) daftarRonde[index].SetActive(true); hewanMasukRondeIni = 0; targetHewanRondeIni = 0; DragHewan[] semuaHewan = daftarRonde[index].GetComponentsInChildren(); foreach (DragHewan h in semuaHewan) { if (h.asalEkosistem != JenisEkosistem.Pengecoh) targetHewanRondeIni++; } } else { AkhiriGame(false); } } void LanjutRondeBerikutnya() { MulaiRonde(rondeSekarang); } void AkhiriGame(bool waktuHabis) { if (gameSelesai) return; gameSelesai = true; float persentaseSkor = totalSemuaHewanGame > 0 ? (float)skorKeseluruhan / totalSemuaHewanGame : 0f; int skorTampil = Mathf.RoundToInt(persentaseSkor * 100f); if(teksSkorAkhir != null) teksSkorAkhir.text = skorTampil.ToString(); int bintangDapat = 0; if (!waktuHabis) { if (persentaseSkor >= 1.00f) bintangDapat = 3; else if (persentaseSkor >= 0.66f) bintangDapat = 2; else if (persentaseSkor >= 0.33f) bintangDapat = 1; } StartCoroutine(AnimasiPanelDanBintang(bintangDapat, waktuHabis)); } IEnumerator AnimasiPanelDanBintang(int jumlahBintang, bool waktuHabis) { if (kontenPanelHasil != null) { kontenPanelHasil.localScale = Vector3.zero; panelHasil.SetActive(true); float t = 0; while (t < 1f) { t += Time.deltaTime * 4f; float curve = Mathf.Sin(t * Mathf.PI * 0.7f) * 1.15f; kontenPanelHasil.localScale = new Vector3(curve, curve, curve); yield return null; } kontenPanelHasil.localScale = Vector3.one; } else { panelHasil.SetActive(true); } if (waktuHabis) { if (speakerGame != null && kasetKalahWaktu != null) speakerGame.PlayOneShot(kasetKalahWaktu); } else { if (speakerGame != null && 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 (speakerGame != null && kasetBenarMasuk != null) speakerGame.PlayOneShot(kasetBenarMasuk); slotBintangPanel[i].color = Color.white; float bT = 0; Vector3 startScale = Vector3.one * 2f; while(bT < 1f){ bT += Time.deltaTime * 5f; slotBintangPanel[i].rectTransform.localScale = Vector3.Lerp(startScale, Vector3.one, bT); yield return null; } yield return new WaitForSeconds(0.4f); } } } public void TombolUlangi() { sudahPernahSapaSortir = false; mauUlangSortir = true; SceneManager.LoadScene(SceneManager.GetActiveScene().name); } public void TombolKeluar() { sudahPernahSapaSortir = false; mauUlangSortir = false; if (speakerGame != null && kasetKlik != null) speakerGame.PlayOneShot(kasetKlik); // Bersihkan sebelum pindah StopAllCoroutines(); if (speakerGame != null) speakerGame.Stop(); SceneManager.LoadScene(SceneManager.GetActiveScene().name); } }