Пример #1
0
        //find path from point A to point B
        public Vector2[] FindPath(Vector2 from, Vector2 to, PathfindingConfig2D config)
        {
            Clear();

            List <Tile> OpenList   = new List <Tile> ();            //list of tiles to check
            List <Tile> ClosedList = new List <Tile> ();            //list of tiles to ignore

            Tile CurrentTile = grid.GetTileFromWorldPosition(from); //current check tile, that to beginning of path searching equal start tile
            Tile toTile      = grid.GetTileFromWorldPosition(to);   //end tile

            if (!toTile.isWalkable)
            {
                return(null);
            }

            OpenList.Add(CurrentTile);
            CurrentTile.State = Tile.listState.Open;

            while (toTile.State != Tile.listState.Close)
            {
                if (OpenList.Count == 0)
                {
                    Debug.Log("Path not found!");
                    return(null);
                }

                OpenList.Remove(CurrentTile);                  //delete current from the open list

                ClosedList.Add(CurrentTile);                   //add current tile to closed list
                CurrentTile.State = Tile.listState.Close;

                CalculateTilesAround(CurrentTile, toTile, OpenList, config); //calculate tile parameters around current tile

                int minF = int.MaxValue;                                     //minimum F value

                //searching tile with minimum F value in open list
                foreach (Tile t in OpenList)
                {
                    if (t.F < minF)
                    {
                        minF = t.F;
                        //current tile equal tile with minimum F value
                        CurrentTile = t;
                    }
                }
            }
            return(PathRecovery(from, to));
        }
Пример #2
0
        //calculate tile parameters around ceterTile
        void CalculateTilesAround(Tile centerTile, Tile toTile, List <Tile> OpenList, PathfindingConfig2D config)
        {
            //loop that ckecks tiles around the central tile
            for (int y = centerTile.y - 1; y <= centerTile.y + 1; y++)
            {
                for (int x = centerTile.x - 1; x <= centerTile.x + 1; x++)
                {
                    //loop values should not be greater than grid size
                    if (x >= 0 && x < grid.GridWidth && y >= 0 && y < grid.GridHeight)
                    {
                        Tile current = grid.tile[x, y];

                        if (!config.DiagonalMovement)
                        {
                            if (x != centerTile.x && y != centerTile.y)
                            {
                                continue;
                            }
                        }

                        if (!current.isWalkable || !ConnerManager(centerTile, current, config))
                        {
                            continue;
                        }

                        //current checked tile should not to be in the closed list
                        if (current.State != Tile.listState.Close)
                        {
                            //if current tile is not in any list
                            if (current.State == Tile.listState.Empty)
                            {
                                current.ParentTile = centerTile;                                 //set central tile as parent tile for current tile

                                CalculateTileValues(current, centerTile, toTile);

                                //add current tile to open list
                                OpenList.Add(current);
                                current.State = Tile.listState.Open;
                            }

                            //if tile is already in open list, we should check the shortest path across this tile
                            //compare the already calculated G value and new G value
                            if (current.State == Tile.listState.Open)
                            {
                                //save the already calculated values ​​of G, H and ParentTile
                                int  oldG          = current.G;
                                int  oldH          = current.H;
                                Tile oldParentTile = current.ParentTile;

                                //calculate new values of G and H
                                current.ParentTile = centerTile;
                                CalculateTileValues(current, centerTile, toTile);

                                //compare old values and new values
                                //if the new value of G is greater than the old G value, then the path is not shorter
                                if (current.G >= oldG)
                                {
                                    //return old values
                                    current.ParentTile = oldParentTile;
                                    current.G          = oldG;
                                    current.H          = oldH;
                                    current.F          = oldH + oldG;
                                }
                            }
                        }
                    }
                }
            }
        }
Пример #3
0
        //returns false if angular movement or angle cut is impossible
        bool ConnerManager(Tile centerTile, Tile current, PathfindingConfig2D config)
        {
            bool canWalk = true;

            //if rule the catting conners is off, then forbid cutting corner                    C - centerTile * - current X - unwalkable tile
            if (!config.IgnoreCorners)
            {
                if (centerTile.x + 1 == current.x && centerTile.y + 1 == current.y)                   //0 X *
                //0 C 0
                {
                    if (!grid.tile [current.x - 1, current.y].isWalkable)                                 //O O O
                    {
                        canWalk = false;
                    }
                }

                if (centerTile.x - 1 == current.x && centerTile.y - 1 == current.y)                   //0 X C
                //0 * 0
                {
                    if (!grid.tile [current.x, current.y + 1].isWalkable)                                 //O O O
                    {
                        canWalk = false;
                    }
                }

                if (centerTile.x - 1 == current.x && centerTile.y + 1 == current.y)                   //* X 0
                //0 C 0
                {
                    if (!grid.tile [current.x + 1, current.y].isWalkable)                                 //O O O
                    {
                        canWalk = false;
                    }
                }

                if (centerTile.x + 1 == current.x && centerTile.y - 1 == current.y)                   //C X 0
                //0 * 0
                {
                    if (!grid.tile [current.x, current.y + 1].isWalkable)                                 //O O O
                    {
                        canWalk = false;
                    }
                }

                if (centerTile.x + 1 == current.x && centerTile.y - 1 == current.y)                   //0 0 0
                //0 C 0
                {
                    if (!grid.tile [current.x - 1, current.y].isWalkable)                                 //O X *
                    {
                        canWalk = false;
                    }
                }

                if (centerTile.x - 1 == current.x && centerTile.y + 1 == current.y)                   //0 0 0
                //0 * 0
                {
                    if (!grid.tile [current.x, current.y - 1].isWalkable)                                 //0 X C
                    {
                        canWalk = false;
                    }
                }

                if (centerTile.x - 1 == current.x && centerTile.y - 1 == current.y)                   //0 0 0
                //0 C 0
                {
                    if (!grid.tile [current.x + 1, current.y].isWalkable)                                 //* X 0
                    {
                        canWalk = false;
                    }
                }

                if (centerTile.x + 1 == current.x && centerTile.y + 1 == current.y)                   //0 0 0
                //0 * 0
                {
                    if (!grid.tile [current.x, current.y - 1].isWalkable)                                 //C X 0
                    {
                        canWalk = false;
                    }
                }
            }
            //if rule the catting conners is on, then check possibility of cutting conner
            else
            {
                if (centerTile.x + 1 == current.x && centerTile.y + 1 == current.y)                   //0 X *  - in this case, the angle cut is impossible
                //0 C X
                {
                    if (!grid.tile [current.x - 1, current.y].isWalkable)                                 //0 0 0
                    {
                        if (!grid.tile [current.x, current.y - 1].isWalkable)
                        {
                            canWalk = false;
                        }
                    }
                }

                if (centerTile.x - 1 == current.x && centerTile.y + 1 == current.y)                   //* X 0  - in this case, the angle cut is impossible
                //X C 0
                {
                    if (!grid.tile [current.x + 1, current.y].isWalkable)                                 //0 0 0
                    {
                        if (!grid.tile [current.x, current.y - 1].isWalkable)
                        {
                            canWalk = false;
                        }
                    }
                }

                if (centerTile.x - 1 == current.x && centerTile.y - 1 == current.y)                   //0 0 0  - in this case, the angle cut is impossible
                //X C 0
                {
                    if (!grid.tile [current.x + 1, current.y].isWalkable)                                 //* X 0
                    {
                        if (!grid.tile [current.x, current.y + 1].isWalkable)
                        {
                            canWalk = false;
                        }
                    }
                }

                if (centerTile.x + 1 == current.x && centerTile.y - 1 == current.y)                   //0 0 0  - in this case, the angle cut is impossible
                //0 C X
                {
                    if (!grid.tile [current.x - 1, current.y].isWalkable)                                 //0 X *
                    {
                        if (!grid.tile [current.x, current.y + 1].isWalkable)
                        {
                            canWalk = false;
                        }
                    }
                }
            }

            return(canWalk);
        }
Пример #4
0
 void OnEnable()
 {
     config = (PathfindingConfig2D)target;
 }