void CalculatePath(Vector3 cp_start, Vector3 cp_target) { grid.Reset(); Tile startTile = grid.TileFromWorldPosition(cp_start); // translate the start position to a grid tile. Tile targetTile = grid.TileFromWorldPosition(cp_target); // translate the target position to a grid tile. List <Tile> openList = new List <Tile>(); // List to check for neighbours. HashSet <Tile> closedList = new HashSet <Tile>(); // HashSet for checked neighbours. // (HashSet for better performance). Vector3[] waypoints = null; bool pathSucces = false; if (!startTile.isWall && !targetTile.isWall) // Only if the start and end tile are walkable initiate the pathfinding. { openList.Add(startTile); // Start with the first tile (Start Position). while (openList.Count > 0) { Tile currentTile = openList[0]; for (int i = 0; i < openList.Count; i++) { // Check if the current node's f-cost is lower or the same as if (openList[i].f < currentTile.f || (openList[i].f == currentTile.f && openList[i].h < currentTile.h)) { currentTile = openList[i]; } } openList.Remove(currentTile); // If the tile has been checked, remove it from the openList. closedList.Add(currentTile); // And add it to the closedList, so it won't be checked again. if (currentTile == targetTile) // If the current tile is the target tile { pathSucces = true; break; } foreach (Tile neighbour in grid.GetNeighbourTiles(currentTile)) { if (neighbour.isWall || closedList.Contains(neighbour)) { continue; // Ignore the neighbour if it's a wall. } int moveCost = currentTile.g + GetManhattenDistance(currentTile, neighbour); if (!openList.Contains(neighbour) || moveCost < neighbour.g) { neighbour.g = moveCost; // Assigns the move cost (g); neighbour.h = GetManhattenDistance(neighbour, targetTile); // the manhatten distance to target (h); neighbour.parent = currentTile; // and sets the current tile to the last tile's parent. if (!openList.Contains(neighbour)) { openList.Add(neighbour); // Adds the neighbours to the openList. } } } } } //yield return null; // Waits for one frame. if (pathSucces) { waypoints = GetFinalPath(startTile, targetTile); // Backtrace the parents to calculate the actual path. } requestManager.FinishedProcessingPath(waypoints, pathSucces); }