public void FindPath(PathRequest request, Action <PathResult> callback) { Stopwatch sw = new Stopwatch(); sw.Start(); Vector3[] waypoints = new Vector3[0]; bool pathSuccess = false; Node startNode = grid.NodeFromWorldPoint(request.pathStart); Node targetNode = grid.NodeFromWorldPoint(request.pathEnd); startNode.parent = startNode; if (startNode.walkable && targetNode.walkable) { Heap <Node> openSet = new Heap <Node>(grid.MaxSize); HashSet <Node> closedSet = new HashSet <Node>(); openSet.Add(startNode); while (openSet.Count > 0) { Node currentNode = openSet.RemoveFirst(); closedSet.Add(currentNode); if (currentNode == targetNode) { sw.Stop(); //print ("Path found: " + sw.ElapsedMilliseconds + " ms"); pathSuccess = true; break; } foreach (Node neighbour in grid.GetNeighbours(currentNode)) { if (!neighbour.walkable || closedSet.Contains(neighbour)) { continue; } float newMovementCostToNeighbour = currentNode.gCost + GetDistance(currentNode, neighbour) + neighbour.movementPenalty; if (newMovementCostToNeighbour < neighbour.gCost || !openSet.Contains(neighbour)) { neighbour.gCost = newMovementCostToNeighbour; neighbour.hCost = GetDistance(neighbour, targetNode); neighbour.parent = currentNode; if (!openSet.Contains(neighbour)) { openSet.Add(neighbour); } else { openSet.UpdateItem(neighbour); } } } } } if (pathSuccess) { waypoints = RetracePath(startNode, targetNode); pathSuccess = waypoints.Length > 0; } callback(new PathResult(waypoints, pathSuccess, request.callback)); }
private void FindPathInternal(int requestId) { bool pathFound = false; PathRequestData prd = _pathRequestDictionary[requestId]; PathData pathData = null; Node startNode = Nodes[prd.startCell.GridPosition.x, prd.startCell.GridPosition.y]; Node endNode = Nodes[prd.endCell.GridPosition.x, prd.endCell.GridPosition.y]; Heap <Node> openSet = new Heap <Node>(_gridWidth * _gridHeight); HashSet <Node> closeSet = new HashSet <Node>(); openSet.Add(startNode); while (openSet.Count > 0) { Node currentNode = openSet.RemoveFirst(); closeSet.Add(currentNode); if (currentNode == endNode) { var retracedPath = RetracePath(startNode, endNode); Vector3[] waypoints = PathToVector3Array(retracedPath); if (waypoints == null) { retracedPath.Add(endNode); waypoints = new Vector3[1] { endNode.CellObj.transform.position }; } pathData = new PathData(waypoints, retracedPath); prd.callback(true, pathData); pathFound = true; break; } foreach (Node neighbour in GetNeighbours(currentNode)) { if (closeSet.Contains(neighbour)) { continue; } int hCostToNeighbor = neighbour.CellObj.Cost; if (prd.ignoreTemplateList != null && neighbour.CellObj.IsOccupied) { if (prd.ignoreTemplateList.Count(template => template.Equals(neighbour.CellObj.Occupant.TemplateID)) > 0) { hCostToNeighbor = 1; } } int movementCostToNeighbour = currentNode.GCost + hCostToNeighbor; if (movementCostToNeighbour < neighbour.GCost || !openSet.Contains(neighbour)) { neighbour.GCost = movementCostToNeighbour; neighbour.HCost = GetDistance(neighbour, endNode); neighbour.Parent = currentNode; if (!openSet.Contains(neighbour)) { openSet.Add(neighbour); } else { openSet.UpdateItem(neighbour); } } } } if (!pathFound) { pathData = new PathData(new Vector3[1] { endNode.CellObj.transform.position }, new List <Node>(1) { endNode }); prd.callback(false, pathData); } _pathRequestDictionary.Remove(requestId); }
public void FindPath(PathRequest request, Action <PathResult> callback) { Stopwatch sw = new Stopwatch(); sw.Start(); Vector3[] waypoints = new Vector3[0]; bool pathSuccess = false; Node2D startNode = grid.NodeFromWorldPoint(request.pathStart); var endNodes = grid.NodesFromWorldBound(request.pathEnd, request.endBounds); UnityEngine.Debug.Log("nodes in end node: " + endNodes.Length); Node2D[] targetNode = endNodes.Where(n => n.walkable).ToArray(); UnityEngine.Debug.Log("usable target nodes: " + targetNode.Length); Node2D endNode = startNode; try { endNode = targetNode[0]; startNode.parent = startNode; if (startNode.walkable && targetNode != null && targetNode.Length > 0) { Heap <Node2D> openSet = new Heap <Node2D>(grid.MaxSize); HashSet <Node2D> closedSet = new HashSet <Node2D>(); openSet.Add(startNode); while (openSet.Count > 0) { Node2D currentNode = openSet.RemoveFirst(); closedSet.Add(currentNode); if (targetNode.Contains(currentNode)) { sw.Stop(); UnityEngine.Debug.Log("Path found: " + sw.ElapsedMilliseconds + " ms"); pathSuccess = true; endNode = currentNode; break; } foreach (Node2D neighbour in grid.GetNeighbours(currentNode)) { if (!neighbour.walkable || closedSet.Contains(neighbour)) { continue; } int newMovementCostToNeighbour = currentNode.gCost + GetDistance(currentNode, neighbour) + neighbour.movementPenalty; if (newMovementCostToNeighbour < neighbour.gCost || !openSet.Contains(neighbour)) { neighbour.gCost = newMovementCostToNeighbour; neighbour.hCost = GetDistance(neighbour, targetNode); neighbour.parent = currentNode; if (!openSet.Contains(neighbour)) { openSet.Add(neighbour); } else { openSet.UpdateItem(neighbour); } } } } } } catch (Exception e) { UnityEngine.Debug.Log("No usable end nodes"); callback(new PathResult(waypoints, pathSuccess, request.callback)); } if (pathSuccess) { waypoints = RetracePath(startNode, endNode); pathSuccess = waypoints.Length > 0; } callback(new PathResult(waypoints, pathSuccess, request.callback)); }
/// <summary> /// A* pathfinding algorithm. /// </summary> /// <param name="request">PathRequest object.</param> /// <param name="callback">Callback object.</param> public void FindPath(PathRequest request, Action <PathResult> callback) { Stopwatch sw = new Stopwatch(); sw.Start(); List <Node> waypoints = new List <Node>(); bool pathSuccess = false; Node startNode = _aGrid.getNode(request.pathStart); Node targetNode = _aGrid.getNode(request.pathEnd); startNode.parent = startNode; if (targetNode.GetState() == Enums.TileState.FREE) { Heap <Node> openSet = new Heap <Node>(_aGrid.MaxSize); HashSet <Node> closedSet = new HashSet <Node>(); openSet.Add(startNode); while (openSet.Count > 0) { Node currentNode = openSet.RemoveFirst(); closedSet.Add(currentNode); if (currentNode == targetNode) { sw.Stop(); //print ("Path found: " + sw.ElapsedMilliseconds + " ms"); pathSuccess = true; break; } foreach (Node neighbour in _aGrid.GetNeighbours(currentNode)) { if (neighbour.GetState() != Enums.TileState.FREE || closedSet.Contains(neighbour)) { continue; } int newMovementCostToNeighbour = currentNode.gCost + GetDistance(currentNode, neighbour) + neighbour.movementPenalty; if (newMovementCostToNeighbour < neighbour.gCost || !openSet.Contains(neighbour)) { neighbour.gCost = newMovementCostToNeighbour; neighbour.hCost = GetDistance(neighbour, targetNode); neighbour.parent = currentNode; if (!openSet.Contains(neighbour)) { openSet.Add(neighbour); } else { openSet.UpdateItem(neighbour); } } } } } if (pathSuccess) { waypoints = RetracePath(startNode, targetNode); pathSuccess = waypoints.Count > 0; } callback(new PathResult(waypoints, pathSuccess, request.parameter, request.callback)); }