MIF_E31230979/Assets/Scripts/CocokGambar/GameManager.cs

370 lines
12 KiB
C#

using UnityEngine;
using UnityEngine.UI;
using System.Collections; // WAJIB ADA untuk IEnumerator (Animasi)
using System.Collections.Generic;
using TMPro;
using UnityEngine.SceneManagement;
public class GameManager : MonoBehaviour
{
public static GameManager instance;
[Header("Sistem Chapter")]
public List<LevelData> semuaChapter;
private int indexChapterSekarang = 0;
[Header("Sistem Skor & Progress")]
public Slider sliderSkor;
public TextMeshProUGUI textSkor;
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 = 1f;
private float waktuTersisa;
private bool gameAktif = false;
[Header("Prefab & Area")]
public GameObject prefabItem;
public GameObject prefabTarget;
public Transform areaTarget;
public Transform areaPilihan;
[Header("Sistem Suara")]
public AudioClip suaraBintang; // Tarik file suara bintang ke sini di Inspector
[Header("UI PopUp & Board Hasil Akhir")]
public GameObject popupWahKeren;
public GameObject popupSalah;
public GameObject panelBoardHasil; // Board Utama (Asset 38)
public GameObject latarHitam; // Panel Hitam Transparan
public TextMeshProUGUI textNilaiAkhir;
public Image hasilBintang1, hasilBintang2, hasilBintang3;
private int jumlahTerselesaikan = 0;
void Awake() { instance = this; }
void Start()
{
skorTarget = 0;
skorSekarangVisual = 0;
if(sliderSkor != null) {
sliderSkor.maxValue = 100;
sliderSkor.value = 0;
}
UpdateVisualSkor();
waktuTersisa = durasiMenit * 60f;
gameAktif = true;
indexChapterSekarang = 0;
if(popupWahKeren != null) popupWahKeren.SetActive(false);
if(popupSalah != null) popupSalah.SetActive(false);
if(panelBoardHasil != null) panelBoardHasil.SetActive(false);
if(latarHitam != null) latarHitam.SetActive(false);
MulaiChapter(0);
}
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;
CheckBintangNyala(skorSekarangVisual, bintang1, bintang2, bintang3);
}
}
public void MunculkanBoardAkhir()
{
if (!gameAktif) return;
gameAktif = false;
// --- TAMBAHKAN KODE SIMPAN DISINI ---
float durasiMain = 0;
TimeTracker tt = FindObjectOfType<TimeTracker>(); // Cari stopwatch
if (tt != null) durasiMain = tt.GetDurasiBermain(); // Ambil detiknya
if (SaveSystem.instance != null)
{
// Simpan: Index 2 (Cocokkan), Skor yang didapat, Durasi waktu
SaveSystem.instance.SimpanHasilGame(2, 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<AudioSource>();
// 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<EfekPopKenyal>())
hasilBintang1.GetComponent<EfekPopKenyal>().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<EfekPopKenyal>())
hasilBintang2.GetComponent<EfekPopKenyal>().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<EfekPopKenyal>())
hasilBintang3.GetComponent<EfekPopKenyal>().enabled = true;
// Kembalikan pitch ke normal setelah selesai
if(audio != null) audio.pitch = 1f;
}
}
void UpdateVisualSkor()
{
if(textSkor != null) textSkor.text = skorTarget.ToString();
}
void CheckBintangNyala(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;
}
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 MulaiChapter(int index)
{
indexChapterSekarang = index;
jumlahTerselesaikan = 0;
foreach (Transform child in areaTarget) Destroy(child.gameObject);
foreach (Transform child in areaPilihan) Destroy(child.gameObject);
LevelData chapterAktif = semuaChapter[indexChapterSekarang];
// 1. MUNCULKAN SILUET (TARGET)
foreach (VegetableData data in chapterAktif.sayurDiChapterIni)
{
GameObject s = Instantiate(prefabTarget, areaTarget);
s.GetComponent<DropZone>().vData = data;
// Pastikan kita ambil RectTransform dari siluet di dalam Slot
if (s.transform.childCount > 0)
{
RectTransform siluetRT = s.transform.GetChild(0).GetComponent<RectTransform>();
if (siluetRT != null)
{
// PAKSA ukuran sesuai data
siluetRT.sizeDelta = data.ukuranCustom;
}
}
}
// 2. KOCOK DAN MUNCULKAN PILIHAN SAYUR (BAWAH)
List<VegetableData> sayurAcak = new List<VegetableData>(chapterAktif.sayurDiChapterIni);
// ... (Logika Shuffle kamu tetap sama di sini) ...
for (int i = 0; i < sayurAcak.Count; i++)
{
VegetableData temp = sayurAcak[i];
int randomIndex = Random.Range(i, sayurAcak.Count);
sayurAcak[i] = sayurAcak[randomIndex];
sayurAcak[randomIndex] = temp;
}
foreach (VegetableData dataPilihan in sayurAcak)
{
GameObject itm = Instantiate(prefabItem, areaPilihan);
itm.GetComponent<DragItem>().vData = dataPilihan;
RectTransform itmRT = itm.GetComponent<RectTransform>();
if (itmRT != null)
{
// PAKSA ukuran pilihan sesuai data
itmRT.sizeDelta = dataPilihan.ukuranCustom;
}
}
// --- RAHASIA AGAR KONSISTEN ---
// Memaksa Unity menghitung ulang layout seketika itu juga
LayoutRebuilder.ForceRebuildLayoutImmediate(areaTarget.GetComponent<RectTransform>());
LayoutRebuilder.ForceRebuildLayoutImmediate(areaPilihan.GetComponent<RectTransform>());
}
// Ganti fungsi TambahSkor yang lama dengan ini
public void TambahSkor()
{
jumlahTerselesaikan++;
LevelData chapterAktif = semuaChapter[indexChapterSekarang];
if (jumlahTerselesaikan >= chapterAktif.sayurDiChapterIni.Count)
{
// Kita panggil Coroutine supaya bisa dikasih jeda waktu
StartCoroutine(JedaMunculPopup());
}
}
IEnumerator JedaMunculPopup()
{
// 1. Kasih jeda (misal 0.8 detik) biar sayur terakhir nempel dulu dengan jelas
yield return new WaitForSeconds(1.5f);
// 2. Tambah skor target (20 poin per chapter)
skorTarget += 20;
UpdateVisualSkor();
// 3. Munculkan popup "Wah Keren"
if(popupWahKeren != null) popupWahKeren.SetActive(true);
// 4. Jeda lagi sebelum pindah chapter (2 detik)
yield return new WaitForSeconds(1.5f);
SembunyikanPopupDanLanjut();
}
void SembunyikanPopupDanLanjut()
{
if(popupWahKeren != null) popupWahKeren.SetActive(false);
if (indexChapterSekarang < semuaChapter.Count - 1)
{
MulaiChapter(indexChapterSekarang + 1);
}
else
{
MunculkanBoardAkhir();
}
}
public void MunculkanWrong()
{
if(popupSalah != null)
{
popupSalah.SetActive(true);
Invoke("SembunyikanWrong", 1f);
}
}
void SembunyikanWrong() { if(popupSalah != null) popupSalah.SetActive(false); }
// --- FUNGSI SUARA (REVISI) ---
public void PutarSuaraKlik()
{
AudioSource audio = GetComponent<AudioSource>();
if (audio != null) audio.Play();
}
// Di dalam class GameManager
public void PutarVO(AudioClip klip)
{
AudioSource audio = GetComponent<AudioSource>();
if (audio != null && klip != null)
{
StartCoroutine(ProsesPutarVO(audio, klip));
}
}
IEnumerator ProsesPutarVO(AudioSource audio, AudioClip klip)
{
// 1. Ambil CanvasGroup dari ChoiceArea untuk mematikan interaksi
CanvasGroup cgArea = areaPilihan.GetComponent<CanvasGroup>();
// Jika belum ada CanvasGroup di Inspector areaPilihan, kodenya akan error.
// Jadi pastikan kamu sudah Add Component 'Canvas Group' di objek ChoiceArea.
if (cgArea != null) cgArea.blocksRaycasts = false;
audio.PlayOneShot(klip);
// 2. Tunggu sampai VO selesai
yield return new WaitForSeconds(klip.length);
// 3. Nyalakan kembali interaksinya
if (cgArea != null) cgArea.blocksRaycasts = true;
}
public void TombolReplay()
{
SceneManager.LoadScene(SceneManager.GetActiveScene().name);
}
public void TombolKembaliMenu()
{
SceneManager.LoadScene("MenuBermain");
}
}