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 void PathfindToTarget(TileObject target, Entity selectedEntity) { frontier.Clear(); visited.Clear(); currentPaths.Clear(); GetTilesInRange(selectedEntity); TileObject requestedTile = GetPathToTarget(target, selectedEntity); selectedEntity.currentTile = requestedTile; selectedEntity.transform.position = requestedTile.transform.position; } 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)) { visited.Add(neighboringTiles); frontier.Enqueue(neighboringTiles); currentPaths.TryAdd(neighboringTiles, currentTile); } } } Debug.Log(frontier.Count); } private TileObject GetPathToTarget(TileObject target, Entity selectedEntity) { TileObject currentTile = target; List pathToTarget = new(); while (currentTile != selectedEntity.currentTile) { pathToTarget.Add(currentTile); currentTile = currentPaths[currentTile]; } pathToTarget.Reverse(); int validMovementRange = Mathf.Min(pathToTarget.Count, selectedEntity.maxMovement) - 1; return pathToTarget[validMovementRange]; } }