119 lines
3.8 KiB
C#
119 lines
3.8 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
using UnityEngine.Tilemaps;
|
|
|
|
public class GridManager : MonoBehaviour
|
|
{
|
|
#region Statication
|
|
|
|
public static GridManager instance;
|
|
|
|
private void Awake()
|
|
{
|
|
if (instance != null && instance != this)
|
|
{
|
|
Destroy(gameObject);
|
|
return;
|
|
}
|
|
instance = this;
|
|
}
|
|
|
|
#endregion
|
|
[SerializeField] private int width;
|
|
[SerializeField] private int height;
|
|
|
|
[SerializeField] private TileObject tilePrefab;
|
|
|
|
[SerializeField] Camera cam;
|
|
|
|
private Dictionary<Vector2, TileObject> allTiles = new();
|
|
[SerializeField] private Transform grid;
|
|
private void Start()
|
|
{
|
|
GenerateGrid();
|
|
cam.transform.position = new Vector3((float)width / 2, (float)height / 2, 0);
|
|
foreach (PlayerEntity player in TurnHandler.instance.playerEntities)
|
|
{
|
|
player.currentTile = GetTileFromWorldPos(player.transform.position);
|
|
player.currentTile.hasUnit = player;
|
|
}
|
|
foreach (Enemy enemy in TurnHandler.instance.enemyEntities)
|
|
{
|
|
enemy.currentTile = GetTileFromWorldPos(enemy.transform.position);
|
|
enemy.currentTile.hasUnit = enemy;
|
|
}
|
|
foreach (Transform spawnLocation in EnemySpawner.instance.spawnLocationPos)
|
|
{
|
|
EnemySpawner.instance.spawnLocations.Add(GetTileFromWorldPos(spawnLocation.position));
|
|
}
|
|
}
|
|
|
|
private void GenerateGrid()
|
|
{
|
|
for (int x = 0; x < width; x++)
|
|
{
|
|
for (int y = 0; y < height; y++)
|
|
{
|
|
Vector2 pos = new Vector2(x - ((float)width / 2) + 0.5f, y - ((float)height / 2) + 0.5f);
|
|
TileObject newTile = Instantiate(tilePrefab, pos, Quaternion.identity);
|
|
newTile.name = $"Tile {x} {y}";
|
|
allTiles[pos] = newTile;
|
|
newTile.transform.SetParent(grid);
|
|
}
|
|
}
|
|
GetTileNeighbors();
|
|
}
|
|
|
|
private void GetTileNeighbors()
|
|
{
|
|
for (int x = 0; x < width; x++)
|
|
{
|
|
for (int y = 0; y < height; y++)
|
|
{
|
|
Vector2 pos = new Vector2(x - ((float)width / 2) + 0.5f, y - ((float)height / 2) + 0.5f);
|
|
TileObject currentTile = allTiles[pos];
|
|
if (GetTileFromWorldPos(pos + Vector2.up)) { currentTile.neighbors.Add(GetTileFromWorldPos(pos+Vector2.up));}
|
|
if (GetTileFromWorldPos(pos + Vector2.down)) { currentTile.neighbors.Add(GetTileFromWorldPos(pos+Vector2.down));}
|
|
if (GetTileFromWorldPos(pos + Vector2.left)) { currentTile.neighbors.Add(GetTileFromWorldPos(pos+Vector2.left));}
|
|
if (GetTileFromWorldPos(pos + Vector2.right)) { currentTile.neighbors.Add(GetTileFromWorldPos(pos+Vector2.right));}
|
|
}
|
|
}
|
|
}
|
|
|
|
public TileObject GetTileFromWorldPos(Vector2 pos)
|
|
{
|
|
if (allTiles.TryGetValue(pos, out TileObject tile))
|
|
{
|
|
return tile;
|
|
}
|
|
return null;
|
|
}
|
|
public TileObject FindClosestEmptyTile(TileObject requestedTile)
|
|
{
|
|
if (!requestedTile.hasUnit)
|
|
{
|
|
return requestedTile;
|
|
}
|
|
Queue<TileObject> frontier = new();
|
|
List<TileObject> visited = new();
|
|
frontier.Enqueue(requestedTile);
|
|
while (frontier.Count > 0)
|
|
{
|
|
TileObject currentTile = frontier.Dequeue();
|
|
foreach (TileObject neighbor in currentTile.neighbors)
|
|
{
|
|
if (!visited.Contains(neighbor))
|
|
{
|
|
if (!neighbor.hasUnit && !neighbor.blocked)
|
|
{
|
|
return neighbor;
|
|
}
|
|
visited.Add(neighbor);
|
|
frontier.Enqueue(neighbor);
|
|
}
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
}
|