/*경로탐색 시작. OpenList에 더이상 남아있는 노드가 없을 때까지 탐색. * OpenList의 노드 중 가장 F가 작은 노드를 다음 currentNode로 정함.*/ void Pathfinding() { ReadMap(); startNode = nodeArray[startPos.y - bottomLeft.y, startPos.x - bottomLeft.x]; endNode = nodeArray[endPos.y - bottomLeft.y, endPos.x - bottomLeft.x]; currentNode = startNode; CloseList.Add(startNode); while (!Search()) { if (OpenList.Count == 0) { warningText.SetActive(true); isDrawn = false; return; } Node temp = null; foreach (Node element in OpenList) { if (temp == null) { temp = element; } else if (temp.F > element.F) { for (int y = -1; y <= 1; y++) { for (int x = -1; x <= 1; x++) { if (currentNode.x + x == element.x && currentNode.y + y == element.y) { temp = element; } } } } } currentNode = temp; OpenList.Remove(temp); CloseList.Add(temp); } GetFinalList(); }
/*현재 노드의 8방위를 확인해서 G와 H를 계산하고 OpenList에 추가. * 아래의 조건에 해당한다면 다음으로 넘어가고, 목표지점에 도달하면 CloseList에 추가하고 종료. * OpenList에 포함된 노드라면 더 작은 F를 갖는 쪽으로 수정.*/ bool Search() { for (int y = -1; y <= 1; y++) { for (int x = -1; x <= 1; x++) { Direction dir = GetDirection(x, y); int arrayX = currentNode.x - bottomLeft.x; int arrayY = currentNode.y - bottomLeft.y; if (arrayX + x < 0 || arrayX + x >= sizeX) { continue; } if (arrayY + y < 0 || arrayY + y >= sizeY) { continue; } Node temp = nodeArray[y + arrayY, x + arrayX]; if (CloseList.Contains(temp)) { continue; } if (temp.isWall) { continue; } if (Corner(dir, arrayX, arrayY)) { continue; } if (Goal(temp)) { endNode.H = CalculateH(temp); endNode.G = CalculateG(dir, currentNode.G); endNode.parentNode = currentNode; CloseList.Add(endNode); return(true); } foreach (Node node in OpenList) { if (temp.x == node.x && temp.y == node.y) { temp.H = node.H; temp.G = node.G; } } if (temp.F == 0) { temp.H = CalculateH(temp); temp.G = CalculateG(dir, currentNode.G); temp.parentNode = currentNode; OpenList.Add(temp); } else { int tempG = CalculateG(dir, currentNode.G); if (temp.G > tempG) { temp.G = tempG; temp.parentNode = currentNode; } } } } return(false); }