IEnumerator FindPath(Vector3 startPos, Vector3 targetPos) { Stopwatch sw = new Stopwatch(); sw.Start(); Vector3[] waypoints = new Vector3[0]; bool pathSuccess = false; Node startNode = grid.NodeFromWorldPoint(startPos); Node targetNode = grid.NodeFromWorldPoint(targetPos); Heap <Node> openSet = new Heap <Node>(grid.MaxSize); HashSet <Node> closedSet = new HashSet <Node>(); openSet.Add(startNode); if (startNode.walkable && targetNode.walkable) { while (openSet.Count > 0) //only breaks if target node is unreacheble { Node currentNode = openSet.RemoveFirst(); closedSet.Add(currentNode); if (currentNode == targetNode) //if goal is reached { sw.Stop(); print("Path found: " + sw.ElapsedMilliseconds + " ms"); pathSuccess = true; break; } foreach (Node neighbour in grid.GetNeighbours(currentNode)) //if open neighbour to current gets a lower gcost from using currents path(patrents), current is the neighbours parent, basically starts here { if (!neighbour.walkable || closedSet.Contains(neighbour)) { continue; } int movenCostToNeighbour = currentNode.gCost + getDistance(currentNode, neighbour); if (movenCostToNeighbour < neighbour.gCost || !openSet.Contains(neighbour)) { neighbour.gCost = movenCostToNeighbour; neighbour.hCost = getDistance(neighbour, targetNode); neighbour.parent = currentNode; if (!openSet.Contains(neighbour)) { openSet.Add(neighbour); } else { openSet.UpdateItem(neighbour); } } } } } yield return(null); if (pathSuccess) { waypoints = RetracePath(startNode, targetNode); } requsetManager.FinishedProcessingPath(waypoints, pathSuccess); }
public void FindPath(PathRequest request, Action <PathResult> callback) { Stopwatch sw = new Stopwatch(); //check how long the method takes sw.Start(); Vector3[] waypoints = new Vector3[0]; //contains the path bool pathSuccess = false; //if path could be found Node startNode = grid.NodeFromWorldPoint(request.pathStart); //get start and end in node Node targetNode = grid.NodeFromWorldPoint(request.pathEnd); Heap <Node> openSet = new Heap <Node>(grid.MaxSize); //create heap for all nodes that can be moved to HashSet <Node> closedSet = new HashSet <Node>(); //hash set for all nodes that can't be moved to openSet.Add(startNode); //add the startnode for a starting point if (startNode.walkable && targetNode.walkable) { while (openSet.Count > 0) //only breaks if target node is unreacheble { Node currentNode = openSet.RemoveFirst(); //set current node to the first one in openSet and remove it from the openset closedSet.Add(currentNode); //so you can't move to current node again if (currentNode == targetNode) //if goal is reached { sw.Stop(); print("Path found: " + sw.ElapsedMilliseconds + " ms"); pathSuccess = true; break; } foreach (Node neighbour in grid.GetNeighbours(currentNode)) //if an open neighbour to the current node gets a lower gcost from using currents path (patrents), current is the neighbours parent { if (!neighbour.walkable || closedSet.Contains(neighbour)) //if neighbour is not walkable or on the closed set skip it { continue; } int movenCostToNeighbour = currentNode.gCost + GetDistance(currentNode, neighbour) + neighbour.movementPenalty; //the cost for moving to the neighbour if (movenCostToNeighbour < neighbour.gCost || !openSet.Contains(neighbour)) //if the new cost is lower than the old or neighbour has not yet been added to openset { neighbour.gCost = movenCostToNeighbour; //set g cost neighbour.hCost = GetDistance(neighbour, targetNode); //set h cost neighbour.parent = currentNode; //set parent to backtrack to start from goal if (!openSet.Contains(neighbour)) //if node was not in openset, add it { openSet.Add(neighbour); } else { openSet.UpdateItem(neighbour); //else, just update heap } } } } } if (pathSuccess) { waypoints = RetracePath(startNode, targetNode); //if path was found, save it in the array pathSuccess = waypoints.Length > 0; } callback(new PathResult(waypoints, pathSuccess, request.callback)); //tell request manager that the path is found //UnityEngine.Debug.Log(GC.GetTotalMemory(true) + " Bytes"); }