public void SetRoute(RouteResult route) { // if we're instructed to move to this tile, we're here! if (route.nodes.Count <= 0) { return; } startMoveTime = Time.deltaTime; currentNodeIndex = 0; // assume we're on the starting Node currentNode = route.nodes[0]; targetNode = route.nodes[1]; }
/// <summary> /// Given a starting and ending node, determine the /// shortest path between the two /// </summary> /// <param name="start">The starting node</param> /// <param name="end">The ending node</param> /// <returns>A RouteResult</returns> public RouteResult Route(Node start, Node end, bool diagonal = true) { // create the result object RouteResult result = new RouteResult(); // create the path for the starting node Path startPath = new Path { cheapestPathCost = 0 }; startPath.nodes.Add(start); // add that path to the dict paths.Add(start.GetInstanceID(), startPath); // create a stack of nodes and queue the starting node Stack nodes = new Stack(); nodes.Push(start); // while we have nodes... while (nodes.Count > 0) { Node current = nodes.Pop() as Node; // retrieve the path for this node if exists in the dictionary pathForKey(current.GetInstanceID(), out Path currentPath); // mark this node as visited in the path currentPath.visited = true; // list of nodes to sort and prioritize next List <Node> nextNodes = new List <Node>(); // for each one fo the nodes neighbors, supporting // both diagonal and direct: List <Node> neighbors = current.directNeighbors; if (diagonal) { neighbors = current.neighbors; } foreach (Node neighborNode in neighbors) { // in the event that a neighbor node gets // removed while pathing or a neighbor is occupied if (neighborNode == null || neighborNode.Occupied) { continue; } // create a new path for this neighbor pathForKey(neighborNode.GetInstanceID(), out Path neighborPath); // determine the cost to get to this node int cost = currentPath.cheapestPathCost + neighborNode.cost; // if the calculated cost is less than the current n.cost (defaults to int.max), // update this as the shortest path to this node if (cost < neighborPath.cheapestPathCost) { neighborPath.cheapestPathCost = cost; neighborPath.nodes.Clear(); // add all nodes in current path to this neighbors nodes foreach (Node shortestNode in currentPath.nodes) { neighborPath.nodes.Add(shortestNode); } // now add this node as well neighborPath.nodes.Add(neighborNode); } // if this node isn't visited, add it to // nextNodes to be sorted and processed if (!neighborPath.visited) { nextNodes.Add(neighborNode); } } // sort all neighbor nodes that haven't been processed // by their distance to the end node and add them to // the stack nextNodes = prioritizeNodes(nextNodes, start, end); foreach (Node nextNode in nextNodes) { nodes.Push(nextNode); } // if this is the end node, set the result and return if (current == end) { result.cost = currentPath.cheapestPathCost; result.nodes = currentPath.nodes; return(result); } } // if no return, return empty result... return(result); }