public PathfindingTile(TileManager.Tile tile, PathfindingTile cameFrom, float cost) { this.tile = tile; this.cameFrom = cameFrom; this.cost = cost; if (cameFrom != null) { pathDistance = cameFrom.pathDistance + 1; } else { pathDistance = 0; } }
public static bool PathExists(TileManager.Tile startTile, TileManager.Tile endTile, bool breakTooLong, int breakAfterTiles, WalkableSetting walkableSetting, DirectionSetting directionSetting) { PathfindingTile currentTile = new PathfindingTile(startTile, null, 0); List <PathfindingTile> frontier = new List <PathfindingTile>() { currentTile }; List <PathfindingTile> checkedTiles = new List <PathfindingTile>() { currentTile }; int breakCounter = 0; while (frontier.Count > 0) { currentTile = frontier[0]; frontier.RemoveAt(0); if (breakTooLong) { if (breakCounter >= breakAfterTiles) { break; } breakCounter += 1; } if (currentTile.tile == endTile) { return(true); } foreach (TileManager.Tile nTile in (directionSetting == DirectionSetting.Horizontal ? currentTile.tile.horizontalSurroundingTiles : (directionSetting == DirectionSetting.Diagonal ? currentTile.tile.diagonalSurroundingTiles : currentTile.tile.surroundingTiles))) { if (nTile != null && checkedTiles.Find(o => o.tile == nTile) == null && (walkableSetting == WalkableSetting.Walkable ? nTile.walkable : (walkableSetting != WalkableSetting.NonWalkable || !nTile.walkable))) { PathfindingTile pTile = new PathfindingTile(nTile, null, Vector2.Distance(nTile.obj.transform.position, endTile.obj.transform.position)); frontier.Add(pTile); checkedTiles.Add(pTile); } } frontier = frontier.OrderBy(o => o.cost).ToList(); } return(false); }
private PathfindingTile[] GetNeighbors(PathfindingTile tile, Vector3 target, Vector3 halfExtends) { List <PathfindingTile> neighbors = new List <PathfindingTile>(); Vector3 pos = new Vector3(tile.Position.x, tile.Position.y, tile.Position.z + 1); List <Collider> colliders = GetCollidersOnTile(pos, halfExtends).ToList(); colliders.RemoveAll(x => x.gameObject.tag == scr_Tags.Human || x.gameObject.tag == scr_Tags.Player); if (colliders.Count == 0) { neighbors.Add(new PathfindingTile(pos, EstimateCosts(pos, target), tile)); } pos = new Vector3(tile.Position.x + 1, tile.Position.y, tile.Position.z); colliders = GetCollidersOnTile(pos, halfExtends).ToList(); colliders.RemoveAll(x => x.gameObject.tag == scr_Tags.Human || x.gameObject.tag == scr_Tags.Player); if (colliders.Count == 0) { neighbors.Add(new PathfindingTile(pos, EstimateCosts(pos, target), tile)); } pos = new Vector3(tile.Position.x, tile.Position.y, tile.Position.z - 1); colliders = GetCollidersOnTile(pos, halfExtends).ToList(); colliders.RemoveAll(x => x.gameObject.tag == scr_Tags.Human || x.gameObject.tag == scr_Tags.Player); if (colliders.Count == 0) { neighbors.Add(new PathfindingTile(pos, EstimateCosts(pos, target), tile)); } pos = new Vector3(tile.Position.x - 1, tile.Position.y, tile.Position.z); colliders = GetCollidersOnTile(pos, halfExtends).ToList(); colliders.RemoveAll(x => x.gameObject.tag == scr_Tags.Human || x.gameObject.tag == scr_Tags.Player); if (colliders.Count == 0) { neighbors.Add(new PathfindingTile(pos, EstimateCosts(pos, target), tile)); } return(neighbors.ToArray()); }
public static List <TileManager.Tile> FindPathToTile(TileManager.Tile startTile, TileManager.Tile endTile, bool allowEndTileNonWalkable) { bool stop = false; if (!allowEndTileNonWalkable && (!endTile.walkable || startTile.region != endTile.region)) { stop = true; } if (!startTile.walkable && endTile.walkable) { stop = false; } if (stop) { return(new List <TileManager.Tile>()); } PathfindingTile currentTile = new PathfindingTile(startTile, null, 0); List <PathfindingTile> frontier = new List <PathfindingTile>() { currentTile }; List <PathfindingTile> checkedTiles = new List <PathfindingTile>() { currentTile }; List <TileManager.Tile> path = new List <TileManager.Tile>(); bool walkable = startTile.walkable; while (frontier.Count > 0) { currentTile = frontier[0]; frontier.RemoveAt(0); if (!walkable && currentTile.tile.walkable) { walkable = true; } if (currentTile.tile == endTile) { while (currentTile.cameFrom != null) { path.Add(currentTile.tile); currentTile = currentTile.cameFrom; } path.Reverse(); return(path); } foreach (TileManager.Tile nTile in (currentTile.tile.surroundingTiles.Find(tile => tile != null && !tile.walkable) != null ? currentTile.tile.horizontalSurroundingTiles : currentTile.tile.surroundingTiles)) { if (nTile != null && checkedTiles.Find(checkedTile => checkedTile.tile == nTile) == null && (allowEndTileNonWalkable && nTile == endTile || (!walkable || nTile.walkable))) { float cost = 0; cost += 1 * Vector2.Distance(nTile.obj.transform.position, endTile.obj.transform.position); cost += 1 * RegionBlockDistance(nTile.regionBlock, endTile.regionBlock, true, true, true); cost += 50 * (nTile.tileType.classes[TileManager.TileType.ClassEnum.LiquidWater] ? 1 : 0); cost += 5 * currentTile.pathDistance; cost -= nTile.map.mapData.mapSize * nTile.walkSpeed; PathfindingTile pTile = new PathfindingTile(nTile, currentTile, cost); frontier.Add(pTile); checkedTiles.Add(pTile); } } frontier = frontier.OrderBy(frontierTile => frontierTile.cost).ToList(); } return(new List <TileManager.Tile>()); }
public ICollection <Vector3> GetPath(Vector3 from, Vector3 to, Vector3 halfExtends) { FoundPath fp = foundPaths.Where(x => x.From == from && x.To == to && x.HalfExtends == halfExtends).FirstOrDefault(); if (fp != null) { return(fp.Path.ToList()); } List <PathfindingTile> closedList = new List <PathfindingTile>(); List <PathfindingTile> openList = new List <PathfindingTile>(); openList.Add(new PathfindingTile(from, EstimateCosts(from, to), null)); int limit = 10000; int limitCounter = 0; while (openList.Where(x => x.Position == to).Count() == 0) { PathfindingTile tileToCheck = openList.OrderBy(x => x.EstimatedCosts).First(); PathfindingTile[] neigh = GetNeighbors(tileToCheck, to, halfExtends); openList.AddRange(neigh.Where(o => closedList.Where(c => c.Position == o.Position).Count() == 0)); openList.Remove(tileToCheck); closedList.Add(tileToCheck); limitCounter++; if (limitCounter > limit) { break; } } List <Vector3> points = new List <Vector3>(); PathfindingTile nextTile = openList.OrderBy(x => x.EstimatedCosts).First(); bool pathFound = false; while (!pathFound) { points.Add(nextTile.Position); if (nextTile.LastTile == null || nextTile.LastTile.Position == from) { pathFound = true; break; } nextTile = nextTile.LastTile; } int counter = 0; List <KeyValuePair <int, Vector3> > pointsWithOrder = new List <KeyValuePair <int, Vector3> >(); for (var i = points.Count - 1; i >= 0; i--) { pointsWithOrder.Add(new KeyValuePair <int, Vector3>(counter, points[i])); counter++; } List <Vector3> path = pointsWithOrder.OrderBy(x => x.Key).Select(x => x.Value).ToList(); foundPaths.Add(new FoundPath(from, to, halfExtends, path.ToArray())); return(path); }
public PathfindingTile(Vector3 tile, int estimatedCosts, PathfindingTile lastTile) { Position = tile; LastTile = lastTile; EstimatedCosts = estimatedCosts + NumberOfTilesBefor(); }