Пример #1
0
    /// <summary>
    /// Coroutine to find the best path according to the DnD* algorithm.
    /// </summary>
    /// <param name="start">Node which starts the path.</param>
    /// <param name="end">Node that ends the path.</param>
    private IEnumerator FindPath(Node start, Node end)
    {
        Node[] nodePath = new Node[0];

        bool pathSuccess = false;

        Node startNode  = start;
        Node targetNode = end;

        // If the target is able to be pathed to...
        if (targetNode.IsWalkable())
        {
            // Prepare sets of nodes for storing information
            List <Node>    openSet   = new List <Node>(grid.length * grid.width); // creates open list of max size equal to max number of tiles in grid
            HashSet <Node> closedSet = new HashSet <Node>();
            openSet.Add(startNode);

            // While there are still nodes left to process...
            while (openSet.Count > 0)
            {
                Node currentNode = openSet[0];

                openSet.RemoveAt(0);

                closedSet.Add(currentNode);

                // Check to see if the node being processed is the target
                if (currentNode == targetNode)
                {
                    pathSuccess = true;
                    break;
                }

                // Get connections from this node
                List <Node> connections = currentNode.connections;

                /// Check every connection for the best next node to check
                foreach (Node connection in connections)
                {
                    if (!connection.IsWalkable() || closedSet.Contains(connection))
                    {
                        // we skip over this connecting node
                        continue;
                    }

                    int newMoveCost = currentNode.gCost + Heuristic(currentNode, connection);

                    if (newMoveCost < connection.gCost || !openSet.Contains(connection))
                    {
                        connection.gCost    = newMoveCost;
                        connection.hCost    = Heuristic(connection, targetNode);
                        connection.fromNode = currentNode;

                        if (!openSet.Contains(connection))
                        {
                            openSet.Add(connection);
                        }
                    }
                }
            }
        }

        yield return(null);

        if (pathSuccess)
        {
            nodePath = RetracePath(startNode, targetNode);
        }
        else
        {
            nodePath = null;
        }

        pathRequester.FreePathfinder(this, nodePath, pathSuccess, endededOnDiagonal);
    }