Files
Savina Rizdafayi d7120c397a Initial commit
2025-07-12 19:53:40 +07:00

106 lines
3.2 KiB
C#

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));
// }
// }
// }
}