[포트폴리오] The Strange Island - Day9

[포트폴리오] The Strange Island - Day9

에이스타를 이용해서 디테일한 경로를 가져오는 기능을 추가하였습니다.

다익스트라로 타일을 특정 갯수 단위로 묶어서 러프한 경로를 얻어낸 후,

얻어낸 경로 타일들을 이용하여 디테일한 경로를 얻어내는 방식으로 구현하였습니다.

// 에이스타를 이용한 디테일 길찾기 // maxFindingCount의 크기만큼만 길을 탐색할 것이기 때문에 도착지나 시작지가 장애물이어도 상관없이 길찾기를한다. // 어차피 대략적인 위치가 나와서 갈팡질팡하는 형태가 나올것이기 때문. public List FindDetailPath(List roughPath, Vector2Int startIndex, Vector2Int endIndex, int maxFindingCount) { if(roughPath == null) { Debug.Log($"시작지나 도착지중 하나가 장애물입니다

" + $"시작지 : {mFinder.DictMap[startIndex].IsObstacle}

" + $"도착지 : {mFinder.DictMap[endIndex].IsObstacle}"); return null; } // 시작지와 도착지가 같으면 시작지의 Index를 반환한다. if (startIndex == endIndex) { Debug.Log("StartEnd Same!"); return new List() { startIndex }; } int startTileRoughID = mFinder.DictMap[startIndex].RoughID; int endTileRoughID = mFinder.DictMap[endIndex].RoughID; int curTileRoughID = startTileRoughID; // 시작지와 도착지의 RoughID가 다르면 즉, 다른 RoughTile에 존재한다면 // 경유지를 지정하여 최종 RoughTile까지 도달할 수 있도록 한다. Vector2Int viaIndex = endIndex; if (startTileRoughID != endTileRoughID) { curTileRoughID = roughPath[0]; viaIndex = FindNearTileIndexByAreaID(startIndex, curTileRoughID); } TileData curTile = mFinder.DictMap[startIndex]; SetTilePathValue(curTile, viaIndex, null, 0.0f); curTile.IsOpen = true; mOpenList.Add(curTile); while (mOpenList.Count > 0) { // 현재 노드를 닫는노드로 바꾼다. curTile.IsOpen = false; mOpenList.Remove(curTile); curTile.IsClosed = true; mCloseList.Add(curTile); mAdjList.Clear(); // 현재 노드의 근처 노드를 가져온다. GetAdjoinTileByObstacleAndOtherID(curTile.Index, ref mAdjList, curTileRoughID); foreach (TileData item in mAdjList) { if (item.IsOpen) { // 이미 OpenList에 들어있는 노드여도 이동할때 드는 비용이 더 적다면 비용과 부모를 수정한다. if (item.G > curTile.G + 1.0f) { item.G = curTile.G = 1.0f; item.H = GetHeuristicValue(startIndex, viaIndex); item.F = item.G + item.H; item.Parent = curTile; } } else { // OpenList에 없다면 값을 설정하고 OpenList에 추가한다. item.IsOpen = true; mOpenList.Add(item); SetTilePathValue(item, viaIndex, curTile, curTile.G + 1.0f); } item.IsOpen = true; } // F값이 가장 적은(총 비용이 가장 적은) 타일을 가져온다. float lowF = float.MaxValue; curTile = null; foreach (TileData item in mOpenList) { if (item.F < lowF) { lowF = item.F; curTile = item; } } // 탐색횟수를 줄이고 탐색횟수가 0 이하가 되면 현재 경로를 반환한다. maxFindingCount--; if (maxFindingCount <= 0) { return GetPathResult(curTile); } else if (curTile.Index == viaIndex) { // 최종 목적지에 다다르면 경로를 반환한다. if (viaIndex == endIndex) { return GetPathResult(curTile); } else { // 경유지에 다다르면 다음 경유지를 목표로 잡고 이동한다. roughPath.RemoveAt(0); if (roughPath.Count <= 0) { viaIndex = endIndex; } else { curTileRoughID = roughPath[0]; viaIndex = FindNearTileIndexByAreaID(curTile.Index, curTileRoughID); } } } } // 모든 타일을 탐색했음에도 찾을 수 없다면 OpenList와 ClosedList를 비우고 null을 반환한다. InitAllPath(); return null; }

장애물이 있는 러프 타일과 일반 타일을 구분하였습니다.

러프타일을 기반으로 에이스타를 활용하여 디테일한 경로를 찾을 수 있습니다.

from http://coding-goblin.tistory.com/33 by ccl(A) rewrite - 2021-10-06 20:00:19