Files
Aplikasi-VR-Edukasi-Mitigas…/Assets/Scripts/PathVisualizer.cs
Savina Rizdafayi d7120c397a Initial commit
2025-07-12 19:53:40 +07:00

250 lines
7.4 KiB
C#

using UnityEngine;
using System.Collections.Generic;
using TMPro;
public class PathVisualizer : MonoBehaviour
{
[Header("Referensi")]
public SetelahGempaUI uiController;
[Header("Visual Jalur")]
public LineRenderer lineRendererPrefab;
private LineRenderer currentLineRenderer;
public Color warnaManhattan = Color.red;
public Color warnaEuclidean = Color.blue;
public AStar_Manhattan pathfinderManhattan;
public AStar_Euclidean pathfinderEuclidean;
public Transform player;
public List<Transform> pintuKeluar;
public Transform zonaAman;
public TMP_Text infoText;
[Header("Opsi")]
public bool gunakanManhattan = false;
public bool gunakanEuclidean = true;
[Header("Daftar Nama Pintu")]
public List<string> namaPintu;
private List<PathResult> multiplePathsEuclidean;
private List<PathResult> multiplePathsManhattan;
private int jalurAktifIndex = 0;
private bool jalurSudahDihitung = false;
void Update()
{
// Jangan lakukan apapun jika UI Setelah Gempa masih aktif
if (uiController != null && uiController.UIAktif)
return;
// Pertama kali tekan X → hitung jalur Euclidean
if (!jalurSudahDihitung)
{
if (Input.GetKeyDown(KeyCode.X) || Input.GetKeyDown(KeyCode.JoystickButton2))
{
gunakanEuclidean = true;
gunakanManhattan = false;
multiplePathsEuclidean = pathfinderEuclidean.FindMultiplePathsMelaluiPintu(
player.position,
zonaAman.position,
AmbilPosisiPintu(),
3,
namaPintu
);
multiplePathsManhattan = null;
jalurAktifIndex = 0;
TampilkanInfoJalurAktif();
jalurSudahDihitung = true;
}
return;
}
// Setelah pertama kali, tekan X lagi → toggle Manhattan/Euclidean
if (Input.GetKeyDown(KeyCode.X) || Input.GetKeyDown(KeyCode.JoystickButton2))
{
gunakanManhattan = !gunakanManhattan;
gunakanEuclidean = !gunakanManhattan;
if (gunakanManhattan && pathfinderManhattan != null)
{
multiplePathsManhattan = pathfinderManhattan.FindMultiplePathsMelaluiPintu(
player.position,
zonaAman.position,
AmbilPosisiPintu(),
3,
namaPintu
);
multiplePathsEuclidean = null;
}
else if (gunakanEuclidean && pathfinderEuclidean != null)
{
multiplePathsEuclidean = pathfinderEuclidean.FindMultiplePathsMelaluiPintu(
player.position,
zonaAman.position,
AmbilPosisiPintu(),
3,
namaPintu
);
multiplePathsManhattan = null;
}
jalurAktifIndex = 0;
TampilkanInfoJalurAktif();
}
// Tombol Y untuk pindah jalur
if (Input.GetKeyDown(KeyCode.Y) || Input.GetKeyDown(KeyCode.JoystickButton3))
{
if (multiplePathsManhattan != null && multiplePathsManhattan.Count > 0)
{
jalurAktifIndex = (jalurAktifIndex + 1) % multiplePathsManhattan.Count;
TampilkanInfoJalurAktif();
}
else if (multiplePathsEuclidean != null && multiplePathsEuclidean.Count > 0)
{
jalurAktifIndex = (jalurAktifIndex + 1) % multiplePathsEuclidean.Count;
TampilkanInfoJalurAktif();
}
}
}
public void HitungDanTampilkanJalur()
{
if (jalurSudahDihitung)
return;
jalurSudahDihitung = true;
if (gunakanManhattan && pathfinderManhattan != null)
{
multiplePathsManhattan = pathfinderManhattan.FindMultiplePathsMelaluiPintu(
player.position,
zonaAman.position,
AmbilPosisiPintu(),
3,
namaPintu
);
multiplePathsEuclidean = null;
}
else if (gunakanEuclidean && pathfinderEuclidean != null)
{
multiplePathsEuclidean = pathfinderEuclidean.FindMultiplePathsMelaluiPintu(
player.position,
zonaAman.position,
AmbilPosisiPintu(),
3,
namaPintu
);
multiplePathsManhattan = null;
}
jalurAktifIndex = 0;
TampilkanInfoJalurAktif();
}
public void ResetJalur()
{
multiplePathsManhattan = null;
multiplePathsEuclidean = null;
jalurAktifIndex = 0;
jalurSudahDihitung = false;
if (infoText != null) infoText.text = "";
}
List<Vector3> AmbilPosisiPintu()
{
List<Vector3> hasil = new List<Vector3>();
foreach (Transform t in pintuKeluar)
hasil.Add(t.position);
return hasil;
}
void TampilkanInfoJalurAktif()
{
PathResult jalur = null;
string mode = gunakanEuclidean ? "1, Lebih Cepat" : "2, Mudah Diikuti";
if (multiplePathsManhattan != null && multiplePathsManhattan.Count > 0)
jalur = multiplePathsManhattan[jalurAktifIndex];
else if (multiplePathsEuclidean != null && multiplePathsEuclidean.Count > 0)
jalur = multiplePathsEuclidean[jalurAktifIndex];
if (jalur != null && infoText != null)
{
string info = $"<b>Mode:</b> {mode}\n" +
$"Jalur #{jalurAktifIndex + 1} - {jalur.keterangan}\n" +
$"Panjang Jalur: {jalur.path.Count} langkah\n" +
$"Estimasi Waktu: {jalur.estimasiWaktu:F2} detik";
if (jalurAktifIndex == 0)
info += "\n<b>Jalur ini adalah jalur tercepat menuju zona aman.</b>";
infoText.text = info;
GambarJalurDenganLineRenderer(jalur.path, gunakanManhattan ? warnaManhattan : warnaEuclidean);
}
}
void GambarJalurDenganLineRenderer(List<Node> path, Color warna)
{
// Hapus line sebelumnya
if (currentLineRenderer != null)
Destroy(currentLineRenderer.gameObject);
if (path == null || path.Count == 0 || lineRendererPrefab == null)
return;
currentLineRenderer = Instantiate(lineRendererPrefab, Vector3.zero, Quaternion.identity);
currentLineRenderer.positionCount = path.Count;
// Atur warna
currentLineRenderer.startColor = warna;
currentLineRenderer.endColor = warna;
for (int i = 0; i < path.Count; i++)
{
currentLineRenderer.SetPosition(i, path[i].worldPosition + Vector3.up * 0.2f);
}
}
void OnDrawGizmos()
{
if (multiplePathsManhattan != null && multiplePathsManhattan.Count > 0)
{
Gizmos.color = Color.red;
List<Node> path = multiplePathsManhattan[jalurAktifIndex].path;
for (int i = 0; i < path.Count - 1; i++)
{
Vector3 start = path[i].worldPosition + Vector3.up * 0.2f;
Vector3 end = path[i + 1].worldPosition + Vector3.up * 0.2f;
Gizmos.DrawLine(start, end);
}
}
if (multiplePathsEuclidean != null && multiplePathsEuclidean.Count > 0)
{
Gizmos.color = Color.cyan;
List<Node> path = multiplePathsEuclidean[jalurAktifIndex].path;
for (int i = 0; i < path.Count - 1; i++)
{
Vector3 start = path[i].worldPosition + Vector3.up * 0.2f;
Vector3 end = path[i + 1].worldPosition + Vector3.up * 0.2f;
Gizmos.DrawLine(start, end);
}
}
}
}