using System.Collections.Generic; using UnityEngine; public class EnemyMovement : MonoBehaviour { #region Statication public static EnemyMovement instance; private void Awake() { if (instance != null && instance != this) { Destroy(gameObject); return; } instance = this; } #endregion private Queue frontier = new(); private HashSet visited = new(); private Dictionary currentPaths = new(); public List pathRequested; public void PathfindToTarget(TileObject target, Entity selectedEntity) { frontier.Clear(); visited.Clear(); currentPaths.Clear(); GetTilesInRange(selectedEntity); GetPathToTarget(GridManager.instance.FindClosestEmptyTile(target), selectedEntity); selectedEntity.currentTile.hasUnit = null; selectedEntity.currentTile.hasUnit = selectedEntity; StartCoroutine(selectedEntity.MoveToLocation(pathRequested.ToArray())); } private void GetTilesInRange(Entity selectedEntity) { frontier.Enqueue(selectedEntity.currentTile); while (frontier.Count > 0) { TileObject currentTile = frontier.Dequeue(); foreach (TileObject neighboringTiles in currentTile.neighbors) { if (!visited.Contains(neighboringTiles) && (!neighboringTiles.hasUnit && !neighboringTiles.blocked)) { visited.Add(neighboringTiles); frontier.Enqueue(neighboringTiles); currentPaths.TryAdd(neighboringTiles, currentTile); } } } } private void GetPathToTarget(TileObject target, Entity selectedEntity) { TileObject currentTile = target; pathRequested.Clear(); while (currentTile != selectedEntity.currentTile) { pathRequested.Add(currentTile); currentTile = currentPaths[currentTile]; } pathRequested.Reverse(); int validMovementRange = Mathf.Min(pathRequested.Count, selectedEntity.maxMovement) - 1; if (pathRequested.Count > selectedEntity.maxMovement) { int tilesToRemove = pathRequested.Count - selectedEntity.maxMovement; pathRequested.RemoveRange(selectedEntity.maxMovement, tilesToRemove); } } }