Scriptum/Assets/Scripts/Pathfinding/NodeMap.cs
2023-01-15 00:53:40 +01:00

163 lines
4.8 KiB
C#

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.Tilemaps;
public class NodeMap : MonoBehaviour
{
public Vector2Int mapSize;
public Node[,] nodeGrid = new Node[0,0];
public float cellSize;
public TileData[] TileDatas;
public Dictionary<TileBase, TileData> DataFromTiles = new Dictionary<TileBase, TileData>();
public bool hasEverRun = false;
public Tilemap tilemap;
// Start is called before the first frame update
void Start()
{
DataFromTiles = new Dictionary<TileBase, TileData>();
foreach (var tileData in TileDatas)
{
foreach (var tile in tileData.Tiles)
{
DataFromTiles.Add(tile, tileData);
}
}
hasEverRun = true;
CreateNodes();
TileCheck();
}
public void Generate()
{
DataFromTiles = new Dictionary<TileBase, TileData>();
foreach (var tileData in TileDatas)
{
foreach (var tile in tileData.Tiles)
{
DataFromTiles.Add(tile, tileData);
}
}
hasEverRun = true;
CreateNodes();
TileCheck();
}
public void TileCheck()
{
foreach (var n in nodeGrid)
{
Vector2Int gridPosition = n.gridPosition;
Vector3Int TileGridPosition = tilemap.WorldToCell(n.worldPosition);
TileBase Tile = tilemap.GetTile(TileGridPosition);
if (Tile == null) continue;
if (!DataFromTiles.ContainsKey(Tile))
{
continue;
}
n.walkable = DataFromTiles[Tile].walkable;
}
}
// Update is called once per frame
void Update()
{
}
public void TeleportTo(GameObject g, Node node)
{
g.transform.position = node.worldPosition;
}
public List<Node> GetNeighbours(Node node)
{
List<Node> neighbours = new List<Node>();
for (int x = -1; x <= 1; x++)
{
for (int y = -1; y <= 1; y++)
{
if (x == 0 && y == 0)
continue;
int checkX = node.gridPosition.x + x;
int checkY = node.gridPosition.y + y;
if (checkX >= 0 && checkX < mapSize.x && checkY >= 0 && checkY < mapSize.y)
{
Node item = nodeGrid[checkX, checkY];
neighbours.Add(item);
}
}
}
return neighbours;
}
public void CreateNodes()
{
nodeGrid = new Node[mapSize.x, mapSize.y];
for (int x = 0; x < nodeGrid.GetLength(0); x++)
{
for (int y = 0; y < nodeGrid.GetLength(1); y++)
{
Vector2Int gridPosition = new Vector2Int(x, y);
nodeGrid[x, y] = new Node(gridPosition, GetWorldPosition(gridPosition));
Vector3Int TileGridPosition = tilemap.WorldToCell(nodeGrid[x,y].worldPosition);
TileBase Tile = tilemap.GetTile(TileGridPosition);
//nodeGrid[x, y].walkable = DataFromTiles[Tile].walkable;
}
}
}
public Node NodeFromWorldPoint(Vector2 worldPosition)
{
float percentX = (worldPosition.x + mapSize.x / 2) / mapSize.x;
float percentY = (worldPosition.y + mapSize.y / 2) / mapSize.y;
percentX = Mathf.Clamp01(percentX);
percentY = Mathf.Clamp01(percentY);
int x = Mathf.RoundToInt((mapSize.x - 1) * percentX);
int y = Mathf.RoundToInt((mapSize.y - 1) * percentY);
return nodeGrid[x, y];
}
public Vector3 GetWorldPosition(Vector2Int position)
{
Vector3 worldBottomLeft = transform.position - (Vector3.right * (mapSize.x / 2)) - (Vector3.up * (mapSize.y / 2));
Vector3 worldPoint = worldBottomLeft + (Vector3.right * position.x) + (Vector3.up * position.y);
Vector3 cellSizeOffset = new Vector3(cellSize / 2, cellSize / 2, 0);
return worldPoint * cellSize + cellSizeOffset;
}
public bool showIndividualNodes;
public void OnDrawGizmos()
{
Gizmos.DrawWireCube(transform.position,new Vector3(mapSize.x,mapSize.y,1) * cellSize);
if (!showIndividualNodes)
{
return;
}
foreach (var n in nodeGrid)
{
Vector3 size = Vector3.one * cellSize;
Gizmos.DrawWireCube(n.worldPosition, size);
}
}
}