Initial commit
This commit is contained in:
173
Assets/Scripts/AStar_Euclidean.cs
Normal file
173
Assets/Scripts/AStar_Euclidean.cs
Normal 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
|
||||
}
|
||||
|
||||
}
|
2
Assets/Scripts/AStar_Euclidean.cs.meta
Normal file
2
Assets/Scripts/AStar_Euclidean.cs.meta
Normal file
@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ef9bf4ecea9224d4aabeacd1732b1afb
|
172
Assets/Scripts/AStar_Manhattan.cs
Normal file
172
Assets/Scripts/AStar_Manhattan.cs
Normal 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
|
||||
}
|
||||
}
|
2
Assets/Scripts/AStar_Manhattan.cs.meta
Normal file
2
Assets/Scripts/AStar_Manhattan.cs.meta
Normal file
@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e40e6abad86eafa4799bcf1aa27f7c6a
|
73
Assets/Scripts/AmbilBarang.cs
Normal file
73
Assets/Scripts/AmbilBarang.cs
Normal 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();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
2
Assets/Scripts/AmbilBarang.cs.meta
Normal file
2
Assets/Scripts/AmbilBarang.cs.meta
Normal file
@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 204e78bc378b84a4fb06d5f75cb69203
|
39
Assets/Scripts/BukaLaci.cs
Normal file
39
Assets/Scripts/BukaLaci.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
2
Assets/Scripts/BukaLaci.cs.meta
Normal file
2
Assets/Scripts/BukaLaci.cs.meta
Normal file
@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 547edb03170410449b240e02b9a7dcd3
|
46
Assets/Scripts/BukaLemari.cs
Normal file
46
Assets/Scripts/BukaLemari.cs
Normal 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);
|
||||
}
|
||||
}
|
2
Assets/Scripts/BukaLemari.cs.meta
Normal file
2
Assets/Scripts/BukaLemari.cs.meta
Normal file
@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e9a4ef42dcd07dc46a668a413a00327f
|
51
Assets/Scripts/BukaPintu1.cs
Normal file
51
Assets/Scripts/BukaPintu1.cs
Normal 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;
|
||||
}
|
||||
}
|
2
Assets/Scripts/BukaPintu1.cs.meta
Normal file
2
Assets/Scripts/BukaPintu1.cs.meta
Normal file
@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3978587ba72176e4bb2674463b47d75d
|
19
Assets/Scripts/BukaTutupList.cs
Normal file
19
Assets/Scripts/BukaTutupList.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
2
Assets/Scripts/BukaTutupList.cs.meta
Normal file
2
Assets/Scripts/BukaTutupList.cs.meta
Normal file
@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: df14e205abf3aaf4faddee16e4f29b94
|
42
Assets/Scripts/CardboardMainController.cs
Normal file
42
Assets/Scripts/CardboardMainController.cs
Normal 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
|
||||
}
|
||||
}
|
2
Assets/Scripts/CardboardMainController.cs.meta
Normal file
2
Assets/Scripts/CardboardMainController.cs.meta
Normal file
@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5093d42961583b24cab4579db161dbb8
|
22
Assets/Scripts/CekOverrideRotasi.cs
Normal file
22
Assets/Scripts/CekOverrideRotasi.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
2
Assets/Scripts/CekOverrideRotasi.cs.meta
Normal file
2
Assets/Scripts/CekOverrideRotasi.cs.meta
Normal file
@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 290a3b986a48a0d4bb33cece35ad96ba
|
49
Assets/Scripts/CursorManager.cs
Normal file
49
Assets/Scripts/CursorManager.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
2
Assets/Scripts/CursorManager.cs.meta
Normal file
2
Assets/Scripts/CursorManager.cs.meta
Normal file
@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 997ee8732defaa44789b2b426cb464c6
|
55
Assets/Scripts/FlowController.cs
Normal file
55
Assets/Scripts/FlowController.cs
Normal 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");
|
||||
}
|
||||
}
|
||||
|
2
Assets/Scripts/FlowController.cs.meta
Normal file
2
Assets/Scripts/FlowController.cs.meta
Normal file
@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e421fada0f1292242b52fa88ffe7115d
|
48
Assets/Scripts/GyroKepala.cs
Normal file
48
Assets/Scripts/GyroKepala.cs
Normal 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;
|
||||
}
|
||||
}
|
2
Assets/Scripts/GyroKepala.cs.meta
Normal file
2
Assets/Scripts/GyroKepala.cs.meta
Normal file
@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6bd646c3a63db9541bd98814be88a431
|
103
Assets/Scripts/MengaturGrid.cs
Normal file
103
Assets/Scripts/MengaturGrid.cs
Normal 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));
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
2
Assets/Scripts/MengaturGrid.cs.meta
Normal file
2
Assets/Scripts/MengaturGrid.cs.meta
Normal file
@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b5b9d1d8f21ae174399d1344a93feb07
|
105
Assets/Scripts/MengaturGridE.cs
Normal file
105
Assets/Scripts/MengaturGridE.cs
Normal 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));
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
|
2
Assets/Scripts/MengaturGridE.cs.meta
Normal file
2
Assets/Scripts/MengaturGridE.cs.meta
Normal file
@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: be5e1599bf4c7794eb9b8e54e0f2838d
|
97
Assets/Scripts/MengaturSlide.cs
Normal file
97
Assets/Scripts/MengaturSlide.cs
Normal 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
2
Assets/Scripts/MengaturSlide.cs.meta
Normal file
2
Assets/Scripts/MengaturSlide.cs.meta
Normal file
@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d96c8db1c880a594f9a7a1d1a49549fa
|
112
Assets/Scripts/MengaturSlideAkhir.cs
Normal file
112
Assets/Scripts/MengaturSlideAkhir.cs
Normal 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.");
|
||||
}
|
||||
}
|
2
Assets/Scripts/MengaturSlideAkhir.cs.meta
Normal file
2
Assets/Scripts/MengaturSlideAkhir.cs.meta
Normal file
@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 54b1f9e00200ff548a2aa84ecc0df0d9
|
94
Assets/Scripts/MengaturSlideGempa.cs
Normal file
94
Assets/Scripts/MengaturSlideGempa.cs
Normal 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
2
Assets/Scripts/MengaturSlideGempa.cs.meta
Normal file
2
Assets/Scripts/MengaturSlideGempa.cs.meta
Normal file
@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f6de83f08d33f5642800c8e239e028c0
|
94
Assets/Scripts/MengaturSlideSetelahGempa.cs
Normal file
94
Assets/Scripts/MengaturSlideSetelahGempa.cs
Normal 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
2
Assets/Scripts/MengaturSlideSetelahGempa.cs.meta
Normal file
2
Assets/Scripts/MengaturSlideSetelahGempa.cs.meta
Normal file
@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c25708c2bb14c1548bf002152ade5373
|
29
Assets/Scripts/MouseLook.cs
Normal file
29
Assets/Scripts/MouseLook.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
|
2
Assets/Scripts/MouseLook.cs.meta
Normal file
2
Assets/Scripts/MouseLook.cs.meta
Normal file
@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e028916a9beeb4549b991f9ed137bb10
|
10
Assets/Scripts/NavigasiMenu.cs
Normal file
10
Assets/Scripts/NavigasiMenu.cs
Normal file
@ -0,0 +1,10 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.SceneManagement;
|
||||
|
||||
public class NavigasiMenu : MonoBehaviour
|
||||
{
|
||||
|
||||
public void StartVR(){
|
||||
UnityEngine.SceneManagement.SceneManager.LoadScene("ModeVR", LoadSceneMode.Single);
|
||||
}
|
||||
}
|
2
Assets/Scripts/NavigasiMenu.cs.meta
Normal file
2
Assets/Scripts/NavigasiMenu.cs.meta
Normal file
@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e64a7b34d252ff649aa8c8a6aa42d7fb
|
16
Assets/Scripts/NewMonoBehaviourScript.cs
Normal file
16
Assets/Scripts/NewMonoBehaviourScript.cs
Normal 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()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
2
Assets/Scripts/NewMonoBehaviourScript.cs.meta
Normal file
2
Assets/Scripts/NewMonoBehaviourScript.cs.meta
Normal file
@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7086912445753044bbeef474cd02b048
|
22
Assets/Scripts/Node.cs
Normal file
22
Assets/Scripts/Node.cs
Normal 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;
|
||||
}
|
||||
}
|
2
Assets/Scripts/Node.cs.meta
Normal file
2
Assets/Scripts/Node.cs.meta
Normal file
@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 67fe9da778ccae743aa6e09aa4e68fba
|
29
Assets/Scripts/NonaktifkanTombol.cs
Normal file
29
Assets/Scripts/NonaktifkanTombol.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
2
Assets/Scripts/NonaktifkanTombol.cs.meta
Normal file
2
Assets/Scripts/NonaktifkanTombol.cs.meta
Normal file
@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 68431fe433c3e254db4d738ffd5156de
|
16
Assets/Scripts/PathResult.cs
Normal file
16
Assets/Scripts/PathResult.cs
Normal 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;
|
||||
}
|
2
Assets/Scripts/PathResult.cs.meta
Normal file
2
Assets/Scripts/PathResult.cs.meta
Normal file
@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b8822bf312c58b2499f1750f629845fe
|
249
Assets/Scripts/PathVisualizer.cs
Normal file
249
Assets/Scripts/PathVisualizer.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
2
Assets/Scripts/PathVisualizer.cs.meta
Normal file
2
Assets/Scripts/PathVisualizer.cs.meta
Normal file
@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d7d44cba5c7ef614990044ca16143848
|
25
Assets/Scripts/Penghapus.cs
Normal file
25
Assets/Scripts/Penghapus.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
2
Assets/Scripts/Penghapus.cs.meta
Normal file
2
Assets/Scripts/Penghapus.cs.meta
Normal file
@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 31b4f5d7883e640448815817d7d15590
|
16
Assets/Scripts/PlayerBergerak.cs
Normal file
16
Assets/Scripts/PlayerBergerak.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
2
Assets/Scripts/PlayerBergerak.cs.meta
Normal file
2
Assets/Scripts/PlayerBergerak.cs.meta
Normal file
@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: da18d2c7aedf483458485566a12cec70
|
79
Assets/Scripts/PlayerBergerak1.cs
Normal file
79
Assets/Scripts/PlayerBergerak1.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
2
Assets/Scripts/PlayerBergerak1.cs.meta
Normal file
2
Assets/Scripts/PlayerBergerak1.cs.meta
Normal file
@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: dd531b6e06eb8b54d93b7cd8b7544daa
|
149
Assets/Scripts/SetelahGempaUI.cs
Normal file
149
Assets/Scripts/SetelahGempaUI.cs
Normal 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; }
|
||||
}
|
||||
|
||||
}
|
2
Assets/Scripts/SetelahGempaUI.cs.meta
Normal file
2
Assets/Scripts/SetelahGempaUI.cs.meta
Normal file
@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: eaba794b84f75c2439e45bf609d17d05
|
16
Assets/Scripts/SimplePlayerMovement.cs
Normal file
16
Assets/Scripts/SimplePlayerMovement.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
|
2
Assets/Scripts/SimplePlayerMovement.cs.meta
Normal file
2
Assets/Scripts/SimplePlayerMovement.cs.meta
Normal file
@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a0ec07078af17854996e663e0dd8b2c3
|
199
Assets/Scripts/StartGempa.cs
Normal file
199
Assets/Scripts/StartGempa.cs
Normal 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();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
2
Assets/Scripts/StartGempa.cs.meta
Normal file
2
Assets/Scripts/StartGempa.cs.meta
Normal file
@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 250855b4b5d207e4bb0340b4e1db5e1e
|
13
Assets/Scripts/TesGyroLangsung.cs
Normal file
13
Assets/Scripts/TesGyroLangsung.cs
Normal 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);
|
||||
}
|
||||
}
|
2
Assets/Scripts/TesGyroLangsung.cs.meta
Normal file
2
Assets/Scripts/TesGyroLangsung.cs.meta
Normal file
@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ce775818be07f9842879e6e570f2fdff
|
60
Assets/Scripts/TombolBerlindung.cs
Normal file
60
Assets/Scripts/TombolBerlindung.cs
Normal 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.");
|
||||
}
|
||||
}
|
||||
}
|
2
Assets/Scripts/TombolBerlindung.cs.meta
Normal file
2
Assets/Scripts/TombolBerlindung.cs.meta
Normal file
@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 783d1b066c8f32a40b4d99b700639516
|
Reference in New Issue
Block a user