public void FindPath(int requestId, Vector3 startPoint, Vector3 endPoint, PathfindingComplete callback, List <string> ignoreTemplateList = null) { GridCell startCell = GridManager.Instance.GetCell(startPoint); GridCell endCell = GridManager.Instance.GetCell(endPoint); if (startCell == null || endCell == null) { PathData pathData = new PathData(new Vector3[1] { endPoint }, new List <Node>(1) { null }); callback(false, pathData); return; } PathRequestData prd = new PathRequestData(startCell, endCell, callback, ignoreTemplateList); if (_pathRequestDictionary.ContainsKey(requestId)) { _pathRequestDictionary[requestId] = prd; } else { _pathRequestQueue.Enqueue(requestId); _pathRequestDictionary.Add(requestId, prd); } }
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); }