Ejemplo n.º 1
0
    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);
    }