private IEnumerator PathSearch() { while (!grid.GridGenerated) { yield return(new WaitForSeconds(0.5f)); } PathNode targetNode = grid.GetNearestWalkableNode(request.pathEnd); PathNode startNode = grid.GetNearestWalkableNode(request.pathStart); waypoints = new Vector3[0]; pathFound = false; if (startNode.walkable && targetNode.walkable) { Heap <PathNode> openSet = new Heap <PathNode>(grid.MaxSize); HashSet <PathNode> closedSet = new HashSet <PathNode>(); openSet.Add(startNode); float timer = Time.realtimeSinceStartup; float maxTime = .01f; while (openSet.Count > 0) { if (Time.realtimeSinceStartup > timer + maxTime) { yield return(null); timer = Time.realtimeSinceStartup; } PathNode currentNode = openSet.RemoveFirst(); closedSet.Add(currentNode); if (currentNode == targetNode) { pathFound = true; break; } foreach (PathNode neighbour in grid.GetNeighbours(currentNode)) { if (!neighbour.walkable || closedSet.Contains(neighbour)) { continue; } int newMoveCostToNeighbour = currentNode.gCost + GetDistance(currentNode, neighbour) + currentNode.movementPenalty; if (newMoveCostToNeighbour < neighbour.gCost || !openSet.Contains(neighbour)) { neighbour.gCost = newMoveCostToNeighbour; neighbour.hCost = GetDistance(neighbour, targetNode); neighbour.parent = currentNode; if (!openSet.Contains(neighbour)) { openSet.Add(neighbour); } else { openSet.UpdateItem(neighbour); } } } } } if (pathFound) { waypoints = RetracePath(startNode, targetNode); pathFound = waypoints.Length > 0; } }