예제 #1
0
    public IEnumerator findPath(Vector2 startingPosition, Vector2 targetPosition)
    {
        Vector2[] waypoints   = new Vector2[0];
        bool      pathSuccess = false;

        var startingTile = worldTileMap[(int)startingPosition.x, (int)startingPosition.y];
        var endTile      = worldTileMap[(int)targetPosition.x, (int)targetPosition.y];

        startingTile.parent = startingTile;

        // Debugging
        // var tPos = new Vector3Int((int)targetPosition.x, (int)targetPosition.y, 0);
        // tilemap.SetTileFlags(tPos, TileFlags.None);
        // tilemap.SetColor(tPos, new Color(0.74f, 0.23f, 0.1f, 1f));

        if (startingTile.walkable && endTile.walkable)
        {
            Heap <WorldTile>    openSet   = new Heap <WorldTile>(mapGenerator.width * mapGenerator.height);
            HashSet <WorldTile> closedSet = new HashSet <WorldTile>();

            openSet.Add(startingTile);

            while (openSet.Count > 0)
            {
                var currentWorldTile = openSet.RemoveFirst();
                closedSet.Add(currentWorldTile);

                // NOTE Debugging
                // tileTools.setTileColor(tilemap, currentWorldTile.worldPosition.x, currentWorldTile.worldPosition.y, new Color(0.74f, 0.23f, 0.1f, 0.1f));
                if ((Mathf.Floor(currentWorldTile.worldPosition.x) == Mathf.Floor(targetPosition.x)) &&
                    (Mathf.Floor(currentWorldTile.worldPosition.y) == Mathf.Floor(targetPosition.y)))
                {
                    pathSuccess = true;
                    break;
                }

                var neighbourTiles = mapGenerator.getNeighbourTiles(currentWorldTile.worldPosition);
                foreach (var neighbour in neighbourTiles)
                {
                    if (!neighbour.walkable || closedSet.Contains(neighbour))
                    {
                        continue;
                    }
                    int newMovementCostToNeighbour = currentWorldTile.gCost + getDistance(currentWorldTile, neighbour);
                    if (newMovementCostToNeighbour < neighbour.gCost || !openSet.Contains(neighbour))
                    {
                        neighbour.gCost  = newMovementCostToNeighbour;
                        neighbour.hCost  = getDistance(neighbour, worldTileMap[(int)targetPosition.x, (int)targetPosition.y]);
                        neighbour.parent = currentWorldTile;
                        if (!openSet.Contains(neighbour))
                        {
                            openSet.Add(neighbour);
                        }
                        else
                        {
                            openSet.UpdateItem(neighbour);
                        }
                    }
                }
            }
            // pathSuccess = true;
            // waypoints = new Vector2[0];
        }
        yield return(null);

        if (pathSuccess)
        {
            waypoints = retracePath(startingTile, endTile);
        }
        requestManager.FinishedProcessingPath(waypoints, pathSuccess);
    }
예제 #2
0
    IEnumerator FindPath(Vector2 startPos, Vector2 targetPos)
    {
        Vector2[] waypoints   = new Vector2[0];
        bool      pathSuccess = false;

        Node startNode  = grid.NodeFromWorldPoint(startPos);
        Node targetNode = grid.NodeFromWorldPoint(targetPos);

        Debug.Log(startNode.walkable && targetNode.walkable);
        if (startNode.walkable && targetNode.walkable)
        {
            List <Node>    openSet   = new List <Node>();
            HashSet <Node> closedSet = new HashSet <Node>();
            openSet.Add(startNode);

            while (openSet.Count > 0)
            {
                Node currentNode = openSet[0];
                for (int i = 1; i < openSet.Count; i++)
                {
                    if (openSet[i].fCost < currentNode.fCost || openSet[i].fCost == currentNode.fCost && openSet[i].hCost < currentNode.hCost)
                    {
                        currentNode = openSet[i];
                    }
                }

                openSet.Remove(currentNode);
                closedSet.Add(currentNode);

                if (currentNode == targetNode)
                {
                    Debug.Log("path successful");
                    pathSuccess = true;
                    break;
                }

                foreach (Node neighbor in grid.GetNeighbors(currentNode))
                {
                    if (!neighbor.walkable || closedSet.Contains(neighbor))
                    {
                        continue;
                    }


                    int newMoveCostToNeighbor = currentNode.gCost + GetDistance(currentNode, neighbor);
                    if (newMoveCostToNeighbor < neighbor.gCost || !openSet.Contains(neighbor))
                    {
                        neighbor.gCost  = newMoveCostToNeighbor;
                        neighbor.hCost  = GetDistance(neighbor, targetNode);
                        neighbor.parent = currentNode;

                        if (!openSet.Contains(neighbor))
                        {
                            openSet.Add(neighbor);
                        }
                    }
                }
            }
        }
        yield return(null);

        if (pathSuccess)
        {
            waypoints = RetracePath(startNode, targetNode);
        }
        requestController.FinishedProcessingPath(waypoints, pathSuccess);
    }