Initial commit

This commit is contained in:
Savina Rizdafayi
2025-07-12 19:53:40 +07:00
commit d7120c397a
933 changed files with 246809 additions and 0 deletions

View File

@ -0,0 +1,173 @@
using System.Collections.Generic;
using UnityEngine;
using System.Diagnostics;
public class AStar_Euclidean : MonoBehaviour
{
public MengaturGridE grid;
public Transform pintuDepan;
public Transform pintuDapur;
public Transform pintuGarasi;
public List<Node> FindPath(Vector3 startPos, Vector3 targetPos)
{
Node startNode = grid.NodeFromWorldPoint(startPos);
Node targetNode = grid.NodeFromWorldPoint(targetPos);
List<Node> openSet = new List<Node>();
HashSet<Node> closedSet = new HashSet<Node>();
openSet.Add(startNode);
while (openSet.Count > 0)
{
Node currentNode = openSet[0];
for (int i = 1; i < openSet.Count; i++)
{
if (openSet[i].fCost < currentNode.fCost ||
(openSet[i].fCost == currentNode.fCost && openSet[i].hCost < currentNode.hCost))
{
currentNode = openSet[i];
}
}
openSet.Remove(currentNode);
closedSet.Add(currentNode);
grid.visitedNodeCount++;
if (currentNode == targetNode)
{
return RetracePath(startNode, targetNode);
}
foreach (Node neighbour in grid.GetNeighbours(currentNode))
{
if (!neighbour.walkable || closedSet.Contains(neighbour)) continue;
int newMovementCostToNeighbour = currentNode.gCost + GetDistance(currentNode, neighbour);
if (newMovementCostToNeighbour < neighbour.gCost || !openSet.Contains(neighbour))
{
neighbour.gCost = newMovementCostToNeighbour;
neighbour.hCost = GetEuclideanDistance(neighbour, targetNode);
neighbour.parent = currentNode;
if (!openSet.Contains(neighbour)) openSet.Add(neighbour);
}
}
}
return null;
}
public PathResult FindCombinedPath(Vector3 start, Vector3 pintu, Vector3 zonaAman, string label = "")
{
System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch();
stopwatch.Start();
List<Node> path1 = FindPath(start, pintu);
List<Node> path2 = FindPath(pintu, zonaAman);
if (path1 == null || path2 == null) return null;
path1.AddRange(path2);
float totalCost = 0f;
for (int i = 1; i < path1.Count; i++)
{
totalCost += GetEuclideanDistance(path1[i - 1], path1[i]);
}
float penalty = GetExitPenalty(pintu);
totalCost += penalty * 10f;
float kecepatanPlayer = 5f;
float waktuTempuh = totalCost / (kecepatanPlayer * 10f);
stopwatch.Stop();
float waktuKomputasi = stopwatch.ElapsedMilliseconds / 1000f;
int jumlahNodeDikunjungi = grid.visitedNodeCount;
UnityEngine.Debug.Log(
$"[Evaluasi A* - {label}]\n" +
$"- Waktu Komputasi: {waktuKomputasi:F4} detik\n" +
$"- Jumlah Node Dikunjungi: {jumlahNodeDikunjungi}\n" +
$"- Panjang Jalur: {path1.Count}\n" +
$"- Total Cost: {totalCost:F2}\n" +
$"- Pintu Keluar: {label}"
);
return new PathResult
{
path = path1,
totalCost = totalCost,
keterangan = label,
estimasiWaktu = waktuTempuh
};
}
public List<PathResult> FindMultiplePathsMelaluiPintu(Vector3 startPos, Vector3 zonaAman, List<Vector3> pintuList, int maxJalur, List<string> namaPintu)
{
List<PathResult> semuaJalur = new List<PathResult>();
for (int i = 0; i < pintuList.Count; i++)
{
Vector3 pintu = pintuList[i];
string label = (namaPintu != null && i < namaPintu.Count) ? namaPintu[i] : $"Pintu ({pintu.x:F0},{pintu.z:F0})";
PathResult jalur = FindCombinedPath(startPos, pintu, zonaAman, label);
if (jalur != null)
{
semuaJalur.Add(jalur);
}
}
semuaJalur.Sort((a, b) => a.estimasiWaktu.CompareTo(b.estimasiWaktu));
return semuaJalur.GetRange(0, Mathf.Min(maxJalur, semuaJalur.Count));
}
List<Node> RetracePath(Node startNode, Node endNode)
{
List<Node> path = new List<Node>();
Node currentNode = endNode;
while (currentNode != startNode)
{
path.Add(currentNode);
currentNode = currentNode.parent;
}
path.Reverse();
return path;
}
int GetDistance(Node a, Node b)
{
int dstX = Mathf.Abs(a.gridX - b.gridX);
int dstY = Mathf.Abs(a.gridY - b.gridY);
if (dstX > dstY)
return 14 * dstY + 10 * (dstX - dstY);
return 14 * dstX + 10 * (dstY - dstX);
}
int GetEuclideanDistance(Node a, Node b)
{
float dx = a.gridX - b.gridX;
float dy = a.gridY - b.gridY;
return Mathf.RoundToInt(Mathf.Sqrt(dx * dx + dy * dy) * 10);
}
float GetExitPenalty(Vector3 pintu)
{
if (pintuDepan != null && Vector3.Distance(pintu, pintuDepan.position) < 1f)
return 2f; // Pintu depan
else if (pintuDapur != null && Vector3.Distance(pintu, pintuDapur.position) < 1f)
return 1f; // Pintu dapur
else if (pintuGarasi != null && Vector3.Distance(pintu, pintuGarasi.position) < 1f)
return 1f; // Pintu garasi
return 0f; // Tidak ada penalty
}
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: ef9bf4ecea9224d4aabeacd1732b1afb

View File

@ -0,0 +1,172 @@
using System.Collections.Generic;
using UnityEngine;
public class AStar_Manhattan : MonoBehaviour
{
public MengaturGrid grid;
public Transform pintuDepan;
public Transform pintuDapur;
public Transform pintuGarasi;
public List<Node> FindPath(Vector3 startPos, Vector3 targetPos)
{
grid.visitedNodeCount = 0;
Node startNode = grid.NodeFromWorldPoint(startPos);
Node targetNode = grid.NodeFromWorldPoint(targetPos);
List<Node> openSet = new List<Node>();
HashSet<Node> closedSet = new HashSet<Node>();
openSet.Add(startNode);
while (openSet.Count > 0)
{
Node currentNode = openSet[0];
for (int i = 1; i < openSet.Count; i++)
{
if (openSet[i].fCost < currentNode.fCost ||
(openSet[i].fCost == currentNode.fCost && openSet[i].hCost < currentNode.hCost))
{
currentNode = openSet[i];
}
}
openSet.Remove(currentNode);
closedSet.Add(currentNode);
grid.visitedNodeCount++;
if (currentNode == targetNode)
return RetracePath(startNode, targetNode);
foreach (Node neighbour in grid.GetNeighbours(currentNode))
{
if (!neighbour.walkable || closedSet.Contains(neighbour)) continue;
int newCost = currentNode.gCost + GetDistance(currentNode, neighbour);
if (newCost < neighbour.gCost || !openSet.Contains(neighbour))
{
neighbour.gCost = newCost;
neighbour.hCost = GetManhattanDistance(neighbour, targetNode);
neighbour.parent = currentNode;
if (!openSet.Contains(neighbour))
openSet.Add(neighbour);
}
}
}
return null;
}
public PathResult FindCombinedPath(Vector3 start, Vector3 pintu, Vector3 zonaAman, string label = "")
{
var stopwatch = new System.Diagnostics.Stopwatch();
stopwatch.Start();
grid.visitedNodeCount = 0;
List<Node> path1 = FindPath(start, pintu);
Node lastNodePath1 = grid.NodeFromWorldPoint(pintu);
List<Node> path2 = FindPath(pintu, zonaAman);
Node lastNodePath2 = grid.NodeFromWorldPoint(zonaAman);
if (path1 == null || path2 == null) return null;
path1.AddRange(path2);
int panjangJalur = path1.Count;
float langkahUnit = 1f;
float kecepatanPlayer = 3f;
// Penalty
float penaltyCost = GetExitPenalty(pintu);
// Hitung total cost
int totalCost = lastNodePath1.gCost + lastNodePath2.gCost + Mathf.RoundToInt(penaltyCost * 10f);
float waktuTempuh = totalCost / (kecepatanPlayer * 10f);
stopwatch.Stop();
float waktuKomputasi = stopwatch.ElapsedMilliseconds / 1000f;
int jumlahNodeDikunjungi = grid.visitedNodeCount;
Debug.Log(
$"[Evaluasi A* - {label}]\n" +
$"- Waktu Komputasi: {waktuKomputasi:F4} detik\n" +
$"- Jumlah Node Dikunjungi: {jumlahNodeDikunjungi}\n" +
$"- Panjang Jalur: {panjangJalur} langkah\n" +
$"- Total Cost: {totalCost}\n" +
$"- Estimasi Waktu Tempuh: {waktuTempuh:F2} detik\n" +
$"- Pintu Keluar: {label}"
);
return new PathResult
{
path = path1,
totalCost = totalCost,
keterangan = label,
panjangJalur = panjangJalur,
estimasiWaktu = waktuTempuh
};
}
public List<PathResult> FindMultiplePathsMelaluiPintu(Vector3 startPos, Vector3 zonaAman, List<Vector3> pintuList, int maxJalur, List<string> namaPintu)
{
List<PathResult> semuaJalur = new List<PathResult>();
for (int i = 0; i < pintuList.Count; i++)
{
Vector3 pintu = pintuList[i];
string label = (namaPintu != null && i < namaPintu.Count) ? namaPintu[i] : $"Pintu ({pintu.x:F0},{pintu.z:F0})";
PathResult jalur = FindCombinedPath(startPos, pintu, zonaAman, label);
if (jalur != null)
semuaJalur.Add(jalur);
}
semuaJalur.Sort((a, b) => a.totalCost.CompareTo(b.totalCost));
return semuaJalur.GetRange(0, Mathf.Min(maxJalur, semuaJalur.Count));
}
List<Node> RetracePath(Node startNode, Node endNode)
{
List<Node> path = new List<Node>();
Node currentNode = endNode;
while (currentNode != startNode)
{
path.Add(currentNode);
currentNode = currentNode.parent;
}
path.Reverse();
return path;
}
int GetDistance(Node a, Node b)
{
return 10 * (Mathf.Abs(a.gridX - b.gridX) + Mathf.Abs(a.gridY - b.gridY));
}
int GetManhattanDistance(Node a, Node b)
{
return 10 * (Mathf.Abs(a.gridX - b.gridX) + Mathf.Abs(a.gridY - b.gridY));
}
float GetExitPenalty(Vector3 pintu)
{
if (pintuDepan != null && Vector3.Distance(pintu, pintuDepan.position) < 1f)
return 2f; // Pintu depan
else if (pintuDapur != null && Vector3.Distance(pintu, pintuDapur.position) < 1f)
return 1f; // Pintu dapur
else if (pintuGarasi != null && Vector3.Distance(pintu, pintuGarasi.position) < 1f)
return 1f; // Pintu garasi
return 0f; // Tidak ada penalty
}
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: e40e6abad86eafa4799bcf1aa27f7c6a

View File

@ -0,0 +1,73 @@
using UnityEngine;
using TMPro;
using System.Collections;
public class AmbilBarang : MonoBehaviour
{
public Transform kameraPlayer;
public float radiusAmbil = 1f;
public LayerMask layerItem;
public GameObject uiListBarang;
public GameObject canvasUtama;
public StartGempa pemicuGempa;
private int totalBarang;
private int barangTersisa;
void Start()
{
totalBarang = 0;
foreach (Transform child in uiListBarang.transform)
{
if (child.GetComponent<TextMeshProUGUI>())
{
totalBarang++;
}
}
barangTersisa = totalBarang;
}
void Update()
{
if (Input.GetKeyDown(KeyCode.JoystickButton0) || Input.GetKeyDown(KeyCode.L))
{
Collider[] hitItems = Physics.OverlapSphere(kameraPlayer.position, radiusAmbil, layerItem);
foreach (var hit in hitItems)
{
string tagBarang = hit.gameObject.tag;
Destroy(hit.gameObject);
HilangkanDariUI(tagBarang);
}
}
}
void HilangkanDariUI(string tagBarang)
{
foreach (Transform child in uiListBarang.transform)
{
if (child.GetComponent<TextMeshProUGUI>() && child.name.ToLower().Contains(tagBarang.ToLower()))
{
child.gameObject.SetActive(false);
barangTersisa--;
break;
}
}
if (barangTersisa <= 0)
{
canvasUtama.SetActive(false);
pemicuGempa.SiapkanGempa();
StartCoroutine(MulaiGempaDenganDelay());
}
IEnumerator MulaiGempaDenganDelay()
{
yield return new WaitForSeconds(3f);
pemicuGempa.MulaiGempa();
}
}
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 204e78bc378b84a4fb06d5f75cb69203

View File

@ -0,0 +1,39 @@
using UnityEngine;
public class BukaLaci : MonoBehaviour
{
public Transform laci; // Objek laci yang digerakkan
public Vector3 posisiTertutup; // Posisi lokal saat tertutup
public Vector3 posisiTerbuka; // Posisi lokal saat terbuka
public Transform pemain; // Objek pemain
public float jarakMaksimal = 2f; // Jarak maksimal untuk membuka laci
private bool terbuka = false;
void Start()
{
// Set posisi awal (jika belum diatur)
if (laci != null)
laci.localPosition = posisiTertutup;
}
void Update()
{
if (laci == null || pemain == null) return;
float jarak = Vector3.Distance(pemain.position, laci.position);
// Cek apakah pemain cukup dekat
if (jarak <= jarakMaksimal && !terbuka)
{
laci.localPosition = posisiTerbuka;
terbuka = true;
}
// Cek apakah pemain menjauh
else if (jarak > jarakMaksimal && terbuka)
{
laci.localPosition = posisiTertutup;
terbuka = false;
}
}
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 547edb03170410449b240e02b9a7dcd3

View File

@ -0,0 +1,46 @@
using UnityEngine;
public class BukaLemari : MonoBehaviour
{
public Transform leftDoor;
public Transform rightDoor;
public float openAngle = 90f;
public Transform player;
public float interactDistance = 2f;
private bool isOpen = false;
private bool hasInteracted = false;
void Update()
{
float distance = Vector3.Distance(player.position, transform.position);
if (distance <= interactDistance && !hasInteracted)
{
// Player mendekat, buka pintu
OpenDoors();
hasInteracted = true;
}
if (distance > interactDistance && isOpen)
{
// Player menjauh, tutup pintu
CloseDoors();
hasInteracted = false;
}
}
void OpenDoors()
{
isOpen = true;
leftDoor.localRotation = Quaternion.Euler(0, openAngle, 0);
rightDoor.localRotation = Quaternion.Euler(0, -openAngle, 0);
}
void CloseDoors()
{
isOpen = false;
leftDoor.localRotation = Quaternion.Euler(0, 0, 0);
rightDoor.localRotation = Quaternion.Euler(0, 0, 0);
}
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: e9a4ef42dcd07dc46a668a413a00327f

View File

@ -0,0 +1,51 @@
using UnityEngine;
public class BukaPintu1 : MonoBehaviour
{
public Transform door;
public float openAngle = 90f;
public float closeAngle = 0f;
public float smoothSpeed = 2f;
private bool open = false;
public AudioSource audioSource;
public AudioClip bukaPintuSound; // Suara pintu buka
private bool soundPlayed = false; // Agar suara tidak berulang
void Update()
{
Quaternion targetRotation = open ?
Quaternion.Euler(0, openAngle, 0) :
Quaternion.Euler(0, closeAngle, 0);
// Rotasi pintu
door.localRotation = Quaternion.Slerp(door.localRotation, targetRotation, Time.deltaTime * smoothSpeed);
}
private void OnTriggerEnter(Collider other)
{
if (other.CompareTag("Player"))
{
open = true;
}
if (!soundPlayed && audioSource != null && bukaPintuSound != null)
{
audioSource.PlayOneShot(bukaPintuSound);
soundPlayed = true;
}
}
private void OnTriggerExit(Collider other)
{
if (other.CompareTag("Player"))
{
open = false;
}
soundPlayed = false;
}
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 3978587ba72176e4bb2674463b47d75d

View File

@ -0,0 +1,19 @@
using UnityEngine;
public class BukaTutupList : MonoBehaviour
{
public GameObject panelListBarang;
public GameObject textToggleHint;
private bool isVisible = true;
void Update()
{
if (Input.GetKeyDown(KeyCode.JoystickButton1) || Input.GetKeyDown(KeyCode.B))
{
isVisible = !isVisible;
panelListBarang.SetActive(isVisible);
textToggleHint.SetActive(isVisible);
}
}
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: df14e205abf3aaf4faddee16e4f29b94

View File

@ -0,0 +1,42 @@
using UnityEngine;
public class CardboardMainController : MonoBehaviour
{
public Camera leftEyeCamera;
public Camera rightEyeCamera;
[Header("Stereo Settings")]
public float eyeSeparation = 0.06f; // jarak antar mata, sesuaikan dengan VRBox
public float focalLength = 1.0f; // jarak fokus
void Start()
{
// Atur viewport camera (just in case)
if (leftEyeCamera != null)
leftEyeCamera.rect = new Rect(0f, 0f, 0.5f, 1f);
if (rightEyeCamera != null)
rightEyeCamera.rect = new Rect(0.5f, 0f, 0.5f, 1f);
UpdateEyePositions();
}
void Update()
{
UpdateEyePositions();
// Bisa tambah kontrol kamera manual atau head tracking di sini
// misal dari mouse atau input lain untuk debug di PC
}
void UpdateEyePositions()
{
if (leftEyeCamera != null)
leftEyeCamera.transform.localPosition = new Vector3(-eyeSeparation / 2f, 0, 0);
if (rightEyeCamera != null)
rightEyeCamera.transform.localPosition = new Vector3(eyeSeparation / 2f, 0, 0);
// Kamera biasanya fokus ke depan, tapi bisa kamu modifikasi jika mau
}
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 5093d42961583b24cab4579db161dbb8

View File

@ -0,0 +1,22 @@
using UnityEngine;
public class CekOverrideRotasi : MonoBehaviour
{
private Quaternion lastRotation;
void Start()
{
lastRotation = transform.rotation;
}
void LateUpdate()
{
if (transform.rotation != lastRotation)
{
Debug.LogWarning("⚠️ ROTASI TELAH DIOVERRIDE");
Debug.Log("Rotasi Baru: " + transform.rotation.eulerAngles);
Debug.Log("Stack Trace:\n" + StackTraceUtility.ExtractStackTrace());
lastRotation = transform.rotation;
}
}
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 290a3b986a48a0d4bb33cece35ad96ba

View File

@ -0,0 +1,49 @@
using UnityEngine;
using UnityEngine.SceneManagement;
public class CursorManager : MonoBehaviour
{
public string gameplaySceneName = "GameScene"; // nama scene gameplay kamu
public string menuSceneName = "MainMenu"; // nama scene main menu kamu
void Start()
{
UpdateCursorState(SceneManager.GetActiveScene().name);
// Subscribe supaya tahu kalau scene berubah
SceneManager.sceneLoaded += OnSceneLoaded;
}
void OnDestroy()
{
SceneManager.sceneLoaded -= OnSceneLoaded;
}
void OnSceneLoaded(Scene scene, LoadSceneMode mode)
{
UpdateCursorState(scene.name);
}
void UpdateCursorState(string sceneName)
{
if (Application.isMobilePlatform) return; // ⛔ Jangan ubah cursor di Android
if (sceneName == menuSceneName)
{
Cursor.lockState = CursorLockMode.None;
Cursor.visible = true;
}
else if (sceneName == gameplaySceneName)
{
Cursor.lockState = CursorLockMode.Locked;
Cursor.visible = false;
}
else
{
Cursor.lockState = CursorLockMode.None;
Cursor.visible = true;
}
}
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 997ee8732defaa44789b2b426cb464c6

View File

@ -0,0 +1,55 @@
using UnityEngine;
using UnityEngine.SceneManagement;
public class FlowController : MonoBehaviour
{
public GameObject canvasTutorial;
public GameObject canvasListBarang;
public GameObject canvasEvakuasi;
public GameObject canvasInfoJalur;
public GameObject canvasSlideAkhir;
public GameObject mencaripath;
public GameObject canvasGempa;
public PlayerBergerak1 kontrolPlayer;
void Start()
{
// Awal hanya canvasTutorial yang aktif
canvasTutorial.SetActive(true);
canvasListBarang.SetActive(false);
canvasEvakuasi.SetActive(false);
canvasInfoJalur.SetActive(false);
if (kontrolPlayer != null)
kontrolPlayer.Gerak = false;
}
public void SelesaiTutorial()
{
canvasTutorial.SetActive(false);
canvasListBarang.SetActive(true);
kontrolPlayer.Gerak = true;
}
public void SelesaiBerlindung()
{
canvasGempa.SetActive(false);
canvasEvakuasi.SetActive(true);
kontrolPlayer.Gerak = true;
}
public void SelesaiEvakuasi()
{
canvasEvakuasi.SetActive(false);
canvasInfoJalur.SetActive(true);
mencaripath.SetActive(true);
canvasSlideAkhir.SetActive(true);
}
public void KembaliKeMenu()
{
SceneManager.LoadScene("MainMenu");
}
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: e421fada0f1292242b52fa88ffe7115d

View File

@ -0,0 +1,48 @@
using UnityEngine;
public class GyroKepala : MonoBehaviour
{
private Gyroscope gyro;
private bool gyroEnabled;
// Koreksi rotasi agar sesuai dengan orientasi Unity
private Quaternion rotationFix = Quaternion.Euler(90f, 0f, -90f);
void Start()
{
Screen.sleepTimeout = SleepTimeout.NeverSleep;
gyroEnabled = EnableGyro();
}
private bool EnableGyro()
{
if (SystemInfo.supportsGyroscope)
{
gyro = Input.gyro;
gyro.enabled = true;
Debug.Log("✅ Gyroscope enabled");
return true;
}
else
{
Debug.LogWarning("❌ Gyroscope not supported on this device.");
return false;
}
}
void Update()
{
if (!gyroEnabled) return;
Quaternion deviceRotation = gyro.attitude;
// Koreksi rotasi dari koordinat perangkat ke Unity
Quaternion correctedRotation = new Quaternion(
deviceRotation.x,
deviceRotation.y,
-deviceRotation.z,
-deviceRotation.w
);
transform.localRotation = rotationFix * correctedRotation;
}
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 6bd646c3a63db9541bd98814be88a431

View File

@ -0,0 +1,103 @@
using System.Collections.Generic;
using UnityEngine;
public class MengaturGrid : MonoBehaviour
{
public LayerMask unwalkableMask;
public Vector2 gridWorldSize;
public float nodeRadius;
[HideInInspector] public int visitedNodeCount = 0;
Node[,] grid;
float nodeDiameter;
int gridSizeX, gridSizeY;
void Awake()
{
nodeDiameter = nodeRadius * 2;
gridSizeX = Mathf.RoundToInt(gridWorldSize.x / nodeDiameter);
gridSizeY = Mathf.RoundToInt(gridWorldSize.y / nodeDiameter);
CreateGrid();
}
void CreateGrid()
{
grid = new Node[gridSizeX, gridSizeY];
Vector3 worldBottomLeft = transform.position - Vector3.right * gridWorldSize.x / 2 - Vector3.forward * gridWorldSize.y / 2;
for (int x = 0; x < gridSizeX; x++)
{
for (int y = 0; y < gridSizeY; y++)
{
Vector3 worldPoint = worldBottomLeft + Vector3.right * (x * nodeDiameter + nodeRadius) + Vector3.forward * (y * nodeDiameter + nodeRadius);
bool walkable = !(Physics.CheckSphere(worldPoint, nodeRadius, unwalkableMask));
grid[x, y] = new Node(walkable, worldPoint, x, y);
}
}
Debug.Log("Ukuran grid: " + gridSizeX + " x " + gridSizeY + " = " + (gridSizeX * gridSizeY) + " node");
}
public Node NodeFromWorldPoint(Vector3 worldPosition)
{
float percentX = (worldPosition.x - transform.position.x + gridWorldSize.x / 2) / gridWorldSize.x;
float percentY = (worldPosition.z - transform.position.z + gridWorldSize.y / 2) / gridWorldSize.y;
percentX = Mathf.Clamp01(percentX);
percentY = Mathf.Clamp01(percentY);
int x = Mathf.RoundToInt((gridSizeX - 1) * percentX);
int y = Mathf.RoundToInt((gridSizeY - 1) * percentY);
return grid[x, y];
}
public List<Node> GetNeighbours(Node node)
{
List<Node> neighbours = new List<Node>();
int[,] arah = new int[,]
{
{ 0, 1 }, // atas
{ 0, -1 }, // bawah
{ 1, 0 }, // kanan
{ -1, 0 } // kiri
};
for (int i = 0; i < arah.GetLength(0); i++)
{
int checkX = node.gridX + arah[i, 0];
int checkY = node.gridY + arah[i, 1];
if (checkX >= 0 && checkX < gridSizeX && checkY >= 0 && checkY < gridSizeY)
{
neighbours.Add(grid[checkX, checkY]);
}
}
return neighbours;
}
// void OnDrawGizmos()
// {
// Gizmos.DrawWireCube(transform.position, new Vector3(gridWorldSize.x, 1, gridWorldSize.y));
// if (grid != null)
// {
// foreach (Node n in grid)
// {
// Gizmos.color = (n.walkable) ? Color.white : Color.red;
// Gizmos.DrawCube(n.worldPosition + Vector3.up * 0.1f, Vector3.one * (nodeRadius * 1.5f));
// }
// }
// }
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: b5b9d1d8f21ae174399d1344a93feb07

View File

@ -0,0 +1,105 @@
using System.Collections.Generic;
using UnityEngine;
public class MengaturGridE : MonoBehaviour
{
public LayerMask unwalkableMask;
public Vector2 gridWorldSize;
public float nodeRadius;
[HideInInspector] public int visitedNodeCount = 0;
Node[,] grid;
float nodeDiameter;
int gridSizeX, gridSizeY;
void Awake()
{
nodeDiameter = nodeRadius * 2;
gridSizeX = Mathf.RoundToInt(gridWorldSize.x / nodeDiameter);
gridSizeY = Mathf.RoundToInt(gridWorldSize.y / nodeDiameter);
CreateGrid();
}
void CreateGrid()
{
grid = new Node[gridSizeX, gridSizeY];
Vector3 worldBottomLeft = transform.position - Vector3.right * gridWorldSize.x / 2 - Vector3.forward * gridWorldSize.y / 2;
for (int x = 0; x < gridSizeX; x++)
{
for (int y = 0; y < gridSizeY; y++)
{
Vector3 worldPoint = worldBottomLeft + Vector3.right * (x * nodeDiameter + nodeRadius) + Vector3.forward * (y * nodeDiameter + nodeRadius);
bool walkable = !(Physics.CheckSphere(worldPoint, nodeRadius, unwalkableMask));
grid[x, y] = new Node(walkable, worldPoint, x, y);
}
}
}
public Node NodeFromWorldPoint(Vector3 worldPosition)
{
float percentX = (worldPosition.x - transform.position.x + gridWorldSize.x / 2) / gridWorldSize.x;
float percentY = (worldPosition.z - transform.position.z + gridWorldSize.y / 2) / gridWorldSize.y;
percentX = Mathf.Clamp01(percentX);
percentY = Mathf.Clamp01(percentY);
int x = Mathf.RoundToInt((gridSizeX - 1) * percentX);
int y = Mathf.RoundToInt((gridSizeY - 1) * percentY);
return grid[x, y];
}
public List<Node> GetNeighbours(Node node)
{
List<Node> neighbours = new List<Node>();
int[,] arah = new int[,]
{
{ 1, 0 }, { -1, 0 }, { 0, 1 }, { 0, -1 }, // 4 arah utama
{ 1, 1 }, { 1, -1 }, { -1, 1 }, { -1, -1 } // 4 arah diagonal
};
for (int i = 0; i < arah.GetLength(0); i++)
{
int checkX = node.gridX + arah[i, 0];
int checkY = node.gridY + arah[i, 1];
if (checkX >= 0 && checkX < gridSizeX && checkY >= 0 && checkY < gridSizeY)
{
//cek tabrakan
if (Mathf.Abs(arah[i, 0]) == 1 && Mathf.Abs(arah[i, 1]) == 1)
{
Node n1 = grid[node.gridX + arah[i, 0], node.gridY];
Node n2 = grid[node.gridX, node.gridY + arah[i, 1]];
if (!n1.walkable || !n2.walkable)
continue; // Lewat diagonal dicegah jika sisi sampingnya tembok
}
neighbours.Add(grid[checkX, checkY]);
}
}
return neighbours;
}
// // Untuk debug visual di editor
// void OnDrawGizmos()
// {
// Gizmos.DrawWireCube(transform.position, new Vector3(gridWorldSize.x, 1, gridWorldSize.y));
// if (grid != null)
// {
// foreach (Node n in grid)
// {
// Gizmos.color = (n.walkable) ? Color.white : Color.red;
// Gizmos.DrawCube(n.worldPosition + Vector3.up * 0.1f, Vector3.one * (nodeRadius * 1.5f));
// }
// }
// }
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: be5e1599bf4c7794eb9b8e54e0f2838d

View File

@ -0,0 +1,97 @@
using UnityEngine;
public class MengaturSlide : MonoBehaviour
{
public GameObject[] slides;
public GameObject slidePanel;
private int currentSlide = 0;
public PlayerBergerak1 kontrolPlayer;
public FlowController flowManager;
public Transform kamera;
public float jarakPanel = 1.5f;
public float offsetYPanel = 0.4f;
public int indexSlideUntukConfirm = 6; //index slide ke- untuk confirm
private float waktuTerakhirNextSlide = -10f;
private float delayMinimumConfirm = 0.2f;
void Start()
{
ShowSlide(0);
if (kontrolPlayer != null)
kontrolPlayer.Gerak = false;
}
public void ShowSlide(int index)
{
for (int i = 0; i < slides.Length; i++)
slides[i].SetActive(i == index);
currentSlide = index;
}
public void NextSlide()
{
if (currentSlide < slides.Length - 1)
{
ShowSlide(currentSlide + 1);
waktuTerakhirNextSlide = Time.time;
}
}
public void PrevSlide()
{
if (currentSlide > 0)
ShowSlide(currentSlide - 1);
}
public void ConfirmSlide()
{
slidePanel.SetActive(false);
if (kontrolPlayer != null)
kontrolPlayer.Gerak = true;
// Panggil flowmanager
if (flowManager != null)
flowManager.SelesaiTutorial();
}
void Update()
{
// Tombol NEXT atau CONFIRM
if (Input.GetKeyDown(KeyCode.JoystickButton1) || Input.GetKeyDown(KeyCode.RightArrow) || Input.GetKeyDown(KeyCode.E))
{
if (currentSlide < indexSlideUntukConfirm)
{
NextSlide();
}
else if (currentSlide == indexSlideUntukConfirm && Time.time - waktuTerakhirNextSlide > delayMinimumConfirm) //agar tidak terlalu cepat berganti
{
ConfirmSlide();
}
}
// Tombol PREV
if (Input.GetKeyDown(KeyCode.JoystickButton0) || Input.GetKeyDown(KeyCode.LeftArrow) || Input.GetKeyDown(KeyCode.Q))
{
PrevSlide();
}
// ENTER manual confirm
if (Input.GetKeyDown(KeyCode.Return))
{
if (currentSlide == indexSlideUntukConfirm && Time.time - waktuTerakhirNextSlide > delayMinimumConfirm)
{
ConfirmSlide();
}
}
}
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: d96c8db1c880a594f9a7a1d1a49549fa

View File

@ -0,0 +1,112 @@
using UnityEngine;
public class MengaturSlideAkhir : MonoBehaviour
{
[Header("Slide dan Kontrol")]
public GameObject[] slides;
public GameObject slidePanel;
private int currentSlide = 0;
public PlayerBergerak1 kontrolPlayer;
public FlowController flowManager;
[Header("Deteksi Posisi Player")]
public Transform player;
public Transform zonaAman;
public float radiusDeteksi = 1.5f;
private bool sudahDekat = false;
[Header("Slide Logic")]
public int indexSlideUntukConfirm = 2; // ⬅️ Ubah sesuai jumlah slide kamu
private float waktuTerakhirNextSlide = -10f;
private float delayMinimumConfirm = 0.2f;
void Start()
{
slidePanel.SetActive(false); // Jangan tampilkan dulu
}
void Update()
{
// Deteksi apakah player sudah cukup dekat dengan zona aman
if (!sudahDekat && Vector3.Distance(player.position, zonaAman.position) <= radiusDeteksi)
{
sudahDekat = true;
MunculkanSlideAkhir();
}
// NEXT
if (Input.GetKeyDown(KeyCode.JoystickButton1) || Input.GetKeyDown(KeyCode.RightArrow) || Input.GetKeyDown(KeyCode.E))
{
if (currentSlide < indexSlideUntukConfirm)
{
NextSlide();
}
else if (currentSlide == indexSlideUntukConfirm && Time.time - waktuTerakhirNextSlide > delayMinimumConfirm)
{
ConfirmSlide();
}
}
// PREV
if (Input.GetKeyDown(KeyCode.JoystickButton0) || Input.GetKeyDown(KeyCode.LeftArrow) || Input.GetKeyDown(KeyCode.Q))
{
PrevSlide();
}
// ENTER untuk Confirm
if (Input.GetKeyDown(KeyCode.Return))
{
if (currentSlide == indexSlideUntukConfirm && Time.time - waktuTerakhirNextSlide > delayMinimumConfirm)
{
ConfirmSlide();
}
}
}
void MunculkanSlideAkhir()
{
slidePanel.SetActive(true);
ShowSlide(0);
if (kontrolPlayer != null)
kontrolPlayer.Gerak = false;
}
void ShowSlide(int index)
{
for (int i = 0; i < slides.Length; i++)
slides[i].SetActive(i == index);
currentSlide = index;
}
public void NextSlide()
{
if (currentSlide < slides.Length - 1)
{
ShowSlide(currentSlide + 1);
waktuTerakhirNextSlide = Time.time;
}
}
public void PrevSlide()
{
if (currentSlide > 0)
{
ShowSlide(currentSlide - 1);
}
}
public void ConfirmSlide()
{
slidePanel.SetActive(false);
if (kontrolPlayer != null)
kontrolPlayer.Gerak = true;
// Panggil flow manager untuk kembali ke menu utama (kalau kamu sudah buat fungsinya)
if (flowManager != null)
flowManager.KembaliKeMenu();
Debug.Log("✅ ConfirmSlide ditekan, kembali ke menu.");
}
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 54b1f9e00200ff548a2aa84ecc0df0d9

View File

@ -0,0 +1,94 @@
using UnityEngine;
public class MengaturSlideGempa : MonoBehaviour
{
public GameObject[] slides;
public GameObject slidePanel;
private int currentSlide = 0;
public PlayerBergerak1 kontrolPlayer;
public int indexSlideUntukConfirm = 5; // 🟢 Kamu atur ini di Inspector
private float waktuTerakhirNextSlide = -10f;
private float delayMinimumConfirm = 0.2f;
void Start()
{
ShowSlide(0);
}
public void ShowSlide(int index)
{
for (int i = 0; i < slides.Length; i++)
slides[i].SetActive(i == index);
currentSlide = index;
}
public void NextSlide()
{
if (currentSlide < slides.Length - 1)
{
ShowSlide(currentSlide + 1);
waktuTerakhirNextSlide = Time.time;
}
}
public void PrevSlide()
{
if (currentSlide > 0)
ShowSlide(currentSlide - 1);
}
public void ConfirmSlide()
{
if (currentSlide != indexSlideUntukConfirm)
{
Debug.LogWarning("❌ ConfirmSlide dipanggil bukan pada index yang ditentukan: " + currentSlide + " ≠ " + indexSlideUntukConfirm);
return;
}
if (Time.time - waktuTerakhirNextSlide < delayMinimumConfirm)
{
Debug.LogWarning("❌ ConfirmSlide terlalu cepat setelah NextSlide. Ditolak.");
return;
}
slidePanel.SetActive(false);
if (kontrolPlayer != null)
kontrolPlayer.Gerak = true;
Debug.Log("ConfirmSlide DIPANGGIL pada slide index: " + currentSlide);
}
void Update()
{
// Tombol NEXT atau CONFIRM
if (Input.GetKeyDown(KeyCode.JoystickButton1) || Input.GetKeyDown(KeyCode.RightArrow) || Input.GetKeyDown(KeyCode.E))
{
if (currentSlide < indexSlideUntukConfirm)
{
NextSlide();
}
else if (currentSlide == indexSlideUntukConfirm && Time.time - waktuTerakhirNextSlide > delayMinimumConfirm)
{
ConfirmSlide();
}
}
// Tombol PREV
if (Input.GetKeyDown(KeyCode.JoystickButton0) || Input.GetKeyDown(KeyCode.LeftArrow) || Input.GetKeyDown(KeyCode.Q))
{
PrevSlide();
}
// ENTER manual confirm
if (Input.GetKeyDown(KeyCode.Return))
{
if (currentSlide == indexSlideUntukConfirm && Time.time - waktuTerakhirNextSlide > delayMinimumConfirm)
{
ConfirmSlide();
}
}
}
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: f6de83f08d33f5642800c8e239e028c0

View File

@ -0,0 +1,94 @@
using UnityEngine;
public class MengaturSlideSetelahGempa : MonoBehaviour
{
public GameObject[] slides;
public GameObject slidePanel;
private int currentSlide = 0;
public PlayerBergerak1 kontrolPlayer;
public int indexSlideUntukConfirm = 5; // 🟢 Kamu atur ini di Inspector
private float waktuTerakhirNextSlide = -10f;
private float delayMinimumConfirm = 0.2f;
void Start()
{
ShowSlide(0);
}
public void ShowSlide(int index)
{
for (int i = 0; i < slides.Length; i++)
slides[i].SetActive(i == index);
currentSlide = index;
}
public void NextSlide()
{
if (currentSlide < slides.Length - 1)
{
ShowSlide(currentSlide + 1);
waktuTerakhirNextSlide = Time.time;
}
}
public void PrevSlide()
{
if (currentSlide > 0)
ShowSlide(currentSlide - 1);
}
public void ConfirmSlide()
{
if (currentSlide != indexSlideUntukConfirm)
{
Debug.LogWarning("❌ ConfirmSlide dipanggil bukan pada index yang ditentukan: " + currentSlide + " ≠ " + indexSlideUntukConfirm);
return;
}
if (Time.time - waktuTerakhirNextSlide < delayMinimumConfirm)
{
Debug.LogWarning("❌ ConfirmSlide terlalu cepat setelah NextSlide. Ditolak.");
return;
}
slidePanel.SetActive(false);
if (kontrolPlayer != null)
kontrolPlayer.Gerak = true;
Debug.Log("ConfirmSlide DIPANGGIL pada slide index: " + currentSlide);
}
void Update()
{
// Tombol NEXT atau CONFIRM
if (Input.GetKeyDown(KeyCode.JoystickButton1) || Input.GetKeyDown(KeyCode.RightArrow) || Input.GetKeyDown(KeyCode.E))
{
if (currentSlide < indexSlideUntukConfirm)
{
NextSlide();
}
else if (currentSlide == indexSlideUntukConfirm && Time.time - waktuTerakhirNextSlide > delayMinimumConfirm)
{
ConfirmSlide();
}
}
// Tombol PREV
if (Input.GetKeyDown(KeyCode.JoystickButton0) || Input.GetKeyDown(KeyCode.LeftArrow) || Input.GetKeyDown(KeyCode.Q))
{
PrevSlide();
}
// ENTER manual confirm
if (Input.GetKeyDown(KeyCode.Return))
{
if (currentSlide == indexSlideUntukConfirm && Time.time - waktuTerakhirNextSlide > delayMinimumConfirm)
{
ConfirmSlide();
}
}
}
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: c25708c2bb14c1548bf002152ade5373

View File

@ -0,0 +1,29 @@
using UnityEngine;
public class MouseLook : MonoBehaviour
{
public float mouseSensitivity = 100f;
float xRotation = 0f; // untuk batasi rotasi vertikal
void Start()
{
Cursor.lockState = CursorLockMode.Locked; // supaya kursor hilang dan mouse terkunci di tengah layar
}
void Update()
{
float mouseX = Input.GetAxis("Mouse X") * mouseSensitivity * Time.deltaTime;
float mouseY = Input.GetAxis("Mouse Y") * mouseSensitivity * Time.deltaTime;
xRotation -= mouseY;
xRotation = Mathf.Clamp(xRotation, -90f, 90f); // supaya gak muter 360 vertikal
// rotasi vertikal kamera (pitch)
transform.localRotation = Quaternion.Euler(xRotation, 0f, 0f);
// rotasi horizontal player (yaw)
transform.parent.Rotate(Vector3.up * mouseX);
}
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: e028916a9beeb4549b991f9ed137bb10

View File

@ -0,0 +1,10 @@
using UnityEngine;
using UnityEngine.SceneManagement;
public class NavigasiMenu : MonoBehaviour
{
public void StartVR(){
UnityEngine.SceneManagement.SceneManager.LoadScene("ModeVR", LoadSceneMode.Single);
}
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: e64a7b34d252ff649aa8c8a6aa42d7fb

View File

@ -0,0 +1,16 @@
using UnityEngine;
public class NewMonoBehaviourScript : MonoBehaviour
{
// Start is called once before the first execution of Update after the MonoBehaviour is created
void Start()
{
}
// Update is called once per frame
void Update()
{
}
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 7086912445753044bbeef474cd02b048

22
Assets/Scripts/Node.cs Normal file
View File

@ -0,0 +1,22 @@
using UnityEngine;
public class Node
{
public bool walkable;
public Vector3 worldPosition;
public int gridX, gridY;
public int gCost;
public int hCost;
public int fCost { get { return gCost + hCost; } }
public Node parent;
public Node(bool _walkable, Vector3 _worldPos, int _gridX, int _gridY)
{
walkable = _walkable;
worldPosition = _worldPos;
gridX = _gridX;
gridY = _gridY;
}
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 67fe9da778ccae743aa6e09aa4e68fba

View File

@ -0,0 +1,29 @@
using UnityEngine;
public class NonaktifkanTombol : MonoBehaviour
{
public GameObject[] semuaTombolBerlindung;
void Start()
{
NonaktifkanSemuaTombol(); // Nonaktifkan saat awal scene
}
public void NonaktifkanSemuaTombol()
{
foreach (GameObject tombol in semuaTombolBerlindung)
{
if (tombol != null)
tombol.SetActive(false);
}
}
public void AktifkanSemuaTombol()
{
foreach (GameObject tombol in semuaTombolBerlindung)
{
if (tombol != null)
tombol.SetActive(true);
}
}
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 68431fe433c3e254db4d738ffd5156de

View File

@ -0,0 +1,16 @@
using System.Collections.Generic;
using UnityEngine;
[System.Serializable]
public class PathResult
{
public List<Node> path;
public float totalCost;
public string keterangan;
public float estimasiWaktu; // waktu dalam detik
public int panjangJalur;
// Property tambahan jika butuh label
public string label => keterangan;
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: b8822bf312c58b2499f1750f629845fe

View File

@ -0,0 +1,249 @@
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);
}
}
}
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: d7d44cba5c7ef614990044ca16143848

View File

@ -0,0 +1,25 @@
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.EventSystems;
public class Penghapus : MonoBehaviour
{
void Start()
{
string currentScene = SceneManager.GetActiveScene().name;
// Hapus canvas & EventSystem yang BUKAN dari scene aktif
foreach (GameObject go in Object.FindObjectsByType<GameObject>(FindObjectsSortMode.None))
{
if (!go.scene.name.Equals(currentScene))
{
if (go.GetComponent<Canvas>() || go.GetComponent<EventSystem>())
{
Debug.Log("Destroy leftover UI: " + go.name);
Destroy(go);
}
}
}
}
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 31b4f5d7883e640448815817d7d15590

View File

@ -0,0 +1,16 @@
using UnityEngine;
using UnityEngine.InputSystem;
public class PlayerBergerak : MonoBehaviour
{
public float speed = 1.5f;
void Update()
{
if (Keyboard.current.spaceKey.wasPressedThisFrame || Gamepad.current?.buttonSouth.isPressed == true)
{
transform.Translate(transform.forward * speed * Time.deltaTime);
}
}
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: da18d2c7aedf483458485566a12cec70

View File

@ -0,0 +1,79 @@
using UnityEngine;
[RequireComponent(typeof(CharacterController))]
public class PlayerBergerak1 : MonoBehaviour
{
public float kecepatan = 5f;
public float gravitasi = -9.81f;
public Transform groundCheck;
public float groundDistance = 0.4f;
public LayerMask groundMask;
public bool Gerak = true;
public Transform kameraVR;
private Vector3 velocity;
private bool isGrounded;
private CharacterController controller;
void Start()
{
controller = GetComponent<CharacterController>();
}
void Update()
{
if (!Gerak) return;
// Apakah player menyentuh tanah
isGrounded = Physics.CheckSphere(groundCheck.position, groundDistance, groundMask);
if (isGrounded && velocity.y < 0)
{
velocity.y = -2f; //
}
float x = Input.GetAxis("Horizontal");
float z = Input.GetAxis("Vertical");
// Ambil arah dari kamera (headset)
Vector3 forward = kameraVR.forward;
Vector3 right = kameraVR.right;
// Hapus komponen vertikal biar tidak naik/turun
forward.y = 0f;
right.y = 0f;
// Normalisasi vektor
forward.Normalize();
right.Normalize();
Vector3 move = (right * x + forward * z);
// Horizontal Move
controller.Move(move * kecepatan * Time.deltaTime);
// Gravitasi
velocity.y += gravitasi * Time.deltaTime;
// Vertikal Move
controller.Move(velocity * Time.deltaTime);
}
public void TeleportKe(Vector3 posisiTarget)
{
CharacterController cc = GetComponent<CharacterController>();
if (cc != null)
{
cc.enabled = false;
// Atur posisi player ke target (Y-nya dikasih offset dikit supaya nggak nyangkut)
transform.position = posisiTarget + new Vector3(0, 0.1f, 0);
// Reset velocity biar ga jatuh lagi
velocity.y = 0;
cc.enabled = true;
}
}
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: dd531b6e06eb8b54d93b7cd8b7544daa

View File

@ -0,0 +1,149 @@
using UnityEngine;
public class SetelahGempaUI : MonoBehaviour
{
public GameObject canvasSetelahGempa; // Parent canvas
public GameObject[] slides; // Panel-panel slide
public GameObject slidePanel; // Panel container (parent dari slides)
public PlayerBergerak1 kontrolPlayer;
public PathVisualizer pathVisualizer;
public int indexSlideUntukConfirm = 5;
private int currentSlide = 0;
private float waktuTerakhirNextSlide = -10f;
private float delayMinimumConfirm = 0.2f;
public FlowController flowController;
public float jarakMax = 2f;
void Start()
{
}
public void TampilkanUI(Transform kamera)
{
if (canvasSetelahGempa == null || kamera == null)
{
Debug.LogWarning("UI atau kamera belum di-assign!");
return;
}
Vector3 arah = kamera.forward;
Ray ray = new Ray(kamera.position, arah);
RaycastHit hit;
Vector3 posisiFinal;
if (Physics.Raycast(ray, out hit, jarakMax))
{
posisiFinal = hit.point - arah * 0.1f;
}
else
{
posisiFinal = kamera.position + arah * jarakMax;
}
posisiFinal.y = 1.6f;
canvasSetelahGempa.transform.position = posisiFinal;
Vector3 arahRotasi = posisiFinal - kamera.position;
arahRotasi.y = 0;
canvasSetelahGempa.transform.rotation = Quaternion.LookRotation(arahRotasi);
canvasSetelahGempa.SetActive(true);
ShowSlide(0);
slidePanel.SetActive(true);
}
void ShowSlide(int index)
{
for (int i = 0; i < slides.Length; i++)
{
slides[i].SetActive(i == index);
}
currentSlide = index;
}
void NextSlide()
{
if (currentSlide < slides.Length - 1)
{
ShowSlide(currentSlide + 1);
waktuTerakhirNextSlide = Time.time;
}
}
void PrevSlide()
{
if (currentSlide > 0)
{
ShowSlide(currentSlide - 1);
}
}
void ConfirmSlide()
{
if (currentSlide != indexSlideUntukConfirm)
{
Debug.LogWarning("❌ Confirm bukan pada slide yang ditentukan.");
return;
}
if (Time.time - waktuTerakhirNextSlide < delayMinimumConfirm)
{
Debug.LogWarning("❌ Confirm terlalu cepat.");
return;
}
slidePanel.SetActive(false);
if (canvasSetelahGempa != null)
canvasSetelahGempa.SetActive(false);
if (kontrolPlayer != null)
kontrolPlayer.Gerak = true;
if (pathVisualizer != null)
pathVisualizer.enabled = true;
if (flowController != null)
flowController.SelesaiEvakuasi();
Debug.Log("✅ Confirm selesai, player bisa bergerak, path ditampilkan.");
}
void Update()
{
if (!canvasSetelahGempa.activeSelf) return;
if (Input.GetKeyDown(KeyCode.JoystickButton1) || Input.GetKeyDown(KeyCode.RightArrow) || Input.GetKeyDown(KeyCode.E))
{
if (currentSlide < indexSlideUntukConfirm)
NextSlide();
else if (currentSlide == indexSlideUntukConfirm && Time.time - waktuTerakhirNextSlide > delayMinimumConfirm)
ConfirmSlide();
}
if (Input.GetKeyDown(KeyCode.JoystickButton0) || Input.GetKeyDown(KeyCode.LeftArrow) || Input.GetKeyDown(KeyCode.Q))
{
PrevSlide();
}
if (Input.GetKeyDown(KeyCode.Return))
{
if (currentSlide == indexSlideUntukConfirm && Time.time - waktuTerakhirNextSlide > delayMinimumConfirm)
ConfirmSlide();
}
}
public bool UIAktif
{
get { return canvasSetelahGempa != null && canvasSetelahGempa.activeSelf; }
}
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: eaba794b84f75c2439e45bf609d17d05

View File

@ -0,0 +1,16 @@
using UnityEngine;
public class SimplePlayerMovement : MonoBehaviour
{
public float moveSpeed = 3f;
void Update()
{
float h = Input.GetAxis("Horizontal");
float v = Input.GetAxis("Vertical");
Vector3 direction = new Vector3(h, 0, v);
transform.Translate(direction * moveSpeed * Time.deltaTime);
}
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: a0ec07078af17854996e663e0dd8b2c3

View File

@ -0,0 +1,199 @@
using UnityEngine;
using System.Collections;
public class StartGempa : MonoBehaviour
{
public FlowController flowController; // Tambahkan ini
public Transform kameraKiri;
public Transform kameraKanan;
public float kekuatan = 0.1f;
public AudioSource audioGempa;
public MengaturSlideGempa slideUI;
public PlayerBergerak1 kontrolPlayer;
public Transform posisiBawahMeja;
public Transform transformPlayer;
public GameObject[] tombolBerlindung;
public NonaktifkanTombol pengaturTombol;
private Vector3 awalKiri;
private Vector3 awalKanan;
private Vector3 posisiAwalPlayer;
private Quaternion rotasiAwalPlayer;
public SetelahGempaUI uiSetelahGempaController;
private Coroutine guncangCoroutine;
void Start()
{
if (slideUI != null)
{
slideUI.kontrolPlayer = kontrolPlayer;
slideUI.gameObject.SetActive(false);
}
}
public void SiapkanGempa()
{
Debug.Log("Gempa disiapkan.");
awalKiri = kameraKiri.localPosition;
awalKanan = kameraKanan.localPosition;
}
public void MulaiGempa()
{
Debug.Log("Gempa dimulai!");
guncangCoroutine = StartCoroutine(Guncang());
StartCoroutine(UISetelahDelay(0.5f));
}
public void TampilkanSlideDekatPlayer(Transform kamera, GameObject panel, float jarakMax = 2f)
{
Vector3 arah = kamera.forward;
Ray ray = new Ray(kamera.position, arah);
RaycastHit hit;
Vector3 posisiFinal;
// Jika ada tembok atau furniture di depan
if (Physics.Raycast(ray, out hit, jarakMax))
{
posisiFinal = hit.point - arah * 0.05f;
}
else
{
posisiFinal = kamera.position + arah * jarakMax;
}
panel.transform.position = posisiFinal;
// Rotasi agar selalu hadap ke kamera/player
Vector3 arahRotasi = posisiFinal - kamera.position;
arahRotasi.y = 0; // hanya rotasi horizontal
panel.transform.rotation = Quaternion.LookRotation(arahRotasi);
}
IEnumerator Guncang()
{
if (audioGempa != null) audioGempa.Play();
while (true)
{
kameraKiri.localPosition = awalKiri + Random.insideUnitSphere * kekuatan;
kameraKanan.localPosition = awalKanan + Random.insideUnitSphere * kekuatan;
yield return null;
}
}
IEnumerator UISetelahDelay(float delay)
{
yield return new WaitForSeconds(delay);
if (slideUI != null)
{
GameObject slidePanel = slideUI.slidePanel;
slidePanel.SetActive(true);
Transform kamera = kameraKiri != null ? kameraKiri : Camera.main.transform;
TampilkanSlideDekatPlayer(kamera, slidePanel, 2f);
}
else
{
Debug.LogWarning("slideUI belum di-assign!");
}
foreach (GameObject tombol in tombolBerlindung)
{
if (tombol != null)
tombol.SetActive(true);
}
if (kontrolPlayer != null)
{
kontrolPlayer.Gerak = true;
}
}
public void HentikanGempa()
{
if (guncangCoroutine != null)
StopCoroutine(guncangCoroutine);
kameraKiri.localPosition = awalKiri;
kameraKanan.localPosition = awalKanan;
if (audioGempa != null) audioGempa.Stop();
Debug.Log("Gempa berhenti total.");
}
public void TeleportKeBawahMeja(Transform targetBerlindung)
{
if (transformPlayer != null && targetBerlindung != null)
{
posisiAwalPlayer = transformPlayer.position;
rotasiAwalPlayer = transformPlayer.rotation;
CharacterController cc = transformPlayer.GetComponent<CharacterController>();
if (cc != null) cc.enabled = false;
if (kontrolPlayer != null)
kontrolPlayer.Gerak = false;
transformPlayer.position = targetBerlindung.position;
transformPlayer.rotation = targetBerlindung.rotation;
Debug.Log("Player dipindahkan ke bawah meja: " + targetBerlindung.name);
HentikanGempa();
StartCoroutine(KembalikanPlayer(4f, cc));
}
}
IEnumerator KembalikanPlayer(float delay, CharacterController cc)
{
yield return new WaitForSeconds(delay);
transformPlayer.position = posisiAwalPlayer;
transformPlayer.rotation = rotasiAwalPlayer;
if (cc != null)
cc.enabled = true;
if (kontrolPlayer != null)
kontrolPlayer.Gerak = true;
Debug.Log("Player dikembalikan ke posisi awal.");
yield return new WaitForSeconds(0.5f); // delay sebelum UI muncul
if (pengaturTombol != null)
pengaturTombol.NonaktifkanSemuaTombol();
Debug.Log("UI muncul di posisi: " + uiSetelahGempaController.transform.position);
if (uiSetelahGempaController != null && kameraKiri != null)
{
uiSetelahGempaController.TampilkanUI(kameraKiri);
}
if (flowController != null)
{
flowController.SelesaiBerlindung();
}
}
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 250855b4b5d207e4bb0340b4e1db5e1e

View File

@ -0,0 +1,13 @@
using UnityEngine;
public class TesGyroLangsung : MonoBehaviour
{
void Update()
{
Quaternion deviceRotation = Input.gyro.attitude;
deviceRotation = new Quaternion(deviceRotation.x, deviceRotation.y, -deviceRotation.z, -deviceRotation.w);
transform.localRotation = deviceRotation;
Debug.Log("Gyro langsung ke kamera: " + deviceRotation.eulerAngles);
}
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: ce775818be07f9842879e6e570f2fdff

View File

@ -0,0 +1,60 @@
using UnityEngine;
public class TombolBerlindung : MonoBehaviour
{
public StartGempa pengaturGempa;
public Transform kameraPemain;
public GameObject lantaiBawahMeja;
public float waktuAktifkanLantai = 5f;
public GameObject uiBerlindung;
public Transform titikBerlindung; //titik tujuan berlindung
private bool sudahBerlindung = false;
void Update()
{
if (sudahBerlindung) return;
if (Input.GetKeyDown(KeyCode.B) || Input.GetKeyDown(KeyCode.JoystickButton3))
{
if (kameraPemain == null) return;
float jarak = Vector3.Distance(transform.position, kameraPemain.position);
if (jarak < 4f)
{
Debug.Log("Berlindung di bawah meja!");
if (lantaiBawahMeja != null)
{
lantaiBawahMeja.SetActive(false);
Debug.Log("Lantai bawah meja dinonaktifkan.");
}
if (pengaturGempa != null && titikBerlindung != null)
{
pengaturGempa.HentikanGempa();
pengaturGempa.TeleportKeBawahMeja(titikBerlindung);
}
gameObject.SetActive(false);
sudahBerlindung = true;
if (uiBerlindung != null)
uiBerlindung.SetActive(true);
Invoke("AktifkanLantai", waktuAktifkanLantai);
}
}
}
void AktifkanLantai()
{
if (lantaiBawahMeja != null)
{
lantaiBawahMeja.SetActive(true);
Debug.Log("Lantai bawah meja diaktifkan kembali.");
}
}
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 783d1b066c8f32a40b4d99b700639516