private void GenerateNodes() { for (int i = 0; i < GridHeight; i++) { for (int j = 0; j < GridWidth; j++) { _grid[i, j] = new NodeHeap(false, new Vector3((-_gridSize.x / 2) + _halfNodeWidth + (i * NodeHeight), _halfNodeWidth, (-_gridSize.y / 2) + _halfNodeWidth + (j * NodeWidth)), i, j); if (Physics.CheckSphere(_grid[i, j].m_vPosition, _halfNodeWidth, _obstacleMask)) { _grid[i, j]._nodeType = NodeHeap.NodeType.blocked; } else { _grid[i, j]._nodeType = NodeHeap.NodeType.open; } } } }
public int GetDistance(NodeHeap nodeA, NodeHeap nodeB) { int distanceX = Mathf.Abs(nodeA.m_iGridX - nodeB.m_iGridX); int distanceY = Mathf.Abs(nodeA.m_iGridY - nodeB.m_iGridY); if (distanceX > distanceY) { return(14 * distanceY + 10 * (distanceX - distanceY)); } return(14 * distanceX + 10 * (distanceY - distanceX)); }
public void AStarPathfind(NodeHeap _startNode, NodeHeap _targetNode) { Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); Heap <NodeHeap> openHeap = new Heap <NodeHeap>((int)_pathGridManager._gridSize.x * (int)_pathGridManager._gridSize.y), closedHeap = new Heap <NodeHeap>((int)_pathGridManager._gridSize.x * (int)_pathGridManager._gridSize.y); openHeap.Add(_startNode); while (openHeap.Count > 0) { NodeHeap currentNode = openHeap.RemoveFirst(); closedHeap.Add(currentNode); if (currentNode == _targetNode) { RetracePath(_startNode, _targetNode); stopWatch.Stop(); print("AStarPathFind() completed in " + stopWatch.ElapsedMilliseconds + " milliseconds."); return; } foreach (NodeHeap neighbour in currentNode._nodeNeighbourList) { if (neighbour._nodeType == NodeHeap.NodeType.blocked || closedHeap.Contains(neighbour)) { continue; } int movementCostToNeighbour = currentNode.m_iGCost + GetDistance(currentNode, neighbour); if (movementCostToNeighbour < neighbour.m_iGCost || !openHeap.Contains(neighbour)) { neighbour.m_iGCost = movementCostToNeighbour; neighbour.m_iHCost = GetDistance(neighbour, _targetNode); neighbour.m_Parent = currentNode; } if (!openHeap.Contains(neighbour)) { openHeap.Add(neighbour); openHeap.UpdateItem(neighbour); } } } }
private void RetracePath(NodeHeap start, NodeHeap end) { List <NodeHeap> path = new List <NodeHeap>(); NodeHeap current = end; while (current != start) { path.Add(current); current = current.m_Parent; } path.Reverse(); _pathGridManager._path = path; }
private void DrawNodes() { NodeHeap playerGridCoordinates = GridLocator(_player.position); NodeHeap targetGridCoordinates = GridLocator(_target.position); for (int i = 0; i < GridHeight; i++) { for (int j = 0; j < GridWidth; j++) { if (_grid[i, j]._nodeType == NodeHeap.NodeType.open) { Gizmos.color = Color.clear; } if (_grid[i, j]._nodeType == NodeHeap.NodeType.blocked) { Gizmos.color = Color.red; } if (_grid[i, j].Equals(playerGridCoordinates)) { Gizmos.color = Color.green; } if (_grid[i, j].Equals(targetGridCoordinates)) { Gizmos.color = Color.magenta; } if (_path.Contains(_grid[i, j])) { Gizmos.color = Color.black; } Gizmos.DrawWireCube(_grid[i, j].m_vPosition, new Vector3(NodeWidth, NodeHeight, NodeHeight)); } } }
private List <NodeHeap> ReturnNeighbours(PathGridManagerHeap pathGridManager, NodeHeap _currentNode) { List <NodeHeap> _neighbourList = new List <NodeHeap>(); for (int x = -1; x <= 1; x++) { for (int y = -1; y <= 1; y++) { if (x == 0 && y == 0) { continue; } if (_currentNode.m_iGridX + x >= 0 && // X cannot be negative. _currentNode.m_iGridY + y >= 0 && // Y cannot be negative. _currentNode.m_iGridX + x <= pathGridManager._gridSize.x - 1 && // X cannot be outside the grid's bounds. _currentNode.m_iGridY + y <= pathGridManager._gridSize.y - 1) // Y cannot be outside the grid's bounds. { _neighbourList.Add(pathGridManager._grid[_currentNode.m_iGridX + x, _currentNode.m_iGridY + y]); } } } return(_neighbourList); }