コード例 #1
0
ファイル: PathManager.cs プロジェクト: rythwh/snowship
 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;
     }
 }
コード例 #2
0
ファイル: PathManager.cs プロジェクト: rythwh/snowship
    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);
    }
コード例 #3
0
    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());
    }
コード例 #4
0
ファイル: PathManager.cs プロジェクト: rythwh/snowship
    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>());
    }
コード例 #5
0
    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);
    }
コード例 #6
0
 public PathfindingTile(Vector3 tile, int estimatedCosts, PathfindingTile lastTile)
 {
     Position       = tile;
     LastTile       = lastTile;
     EstimatedCosts = estimatedCosts + NumberOfTilesBefor();
 }