/// <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); }