private NativeArray <PathNode> GridToNative(int2 endPosition) { GridData[,] grid = grid_map.Instance.Grid; NativeArray <PathNode> pathNodeArray = new NativeArray <PathNode>(grid.GetLength(0) * grid.GetLength(1), Allocator.TempJob); for (int x = 0; x < grid.GetLength(0); x++) { for (int y = 0; y < grid.GetLength(1); y++) { PathNode pathNode = new PathNode(); pathNode.x = x; pathNode.y = y; pathNode.index = CalculateIndex(x, y, grid.GetLength(0)); pathNode.costG = int.MaxValue; pathNode.costH = CalculateDistanceCost(new int2(x, y), endPosition); pathNode.CalculateCostF(); pathNode.isWalkable = grid[x, y].IsWalkable; pathNode.weight = grid[x, y].Weight; pathNode.indexPrev = -1; pathNodeArray[pathNode.index] = pathNode; } } return(pathNodeArray); }
public void Execute() { // // * testing // int2 gridSize = new int2(134, 98); // NativeArray<PathNode> pathNodeArray = new NativeArray<PathNode>(gridSize.x * gridSize.y, Allocator.Temp); // for (int x = 0; x < gridSize.x; x++) // { // for (int y = 0; y < gridSize.y; y++) // { // PathNode pathNode = new PathNode(); // pathNode.x = x; // pathNode.y = y; // pathNode.index = CalculateIndex(x, y, gridSize.x); // pathNode.costG = int.MaxValue; // pathNode.costH = CalculateDistanceCost(new int2(x, y), endPosition); // pathNode.CalculateCostF(); // pathNode.isWalkable = true; // // pathNode.weight = ?; // pathNode.indexPrev = -1; // pathNodeArray[pathNode.index] = pathNode; // } // } // // * testing // PathNode walkablePathNode = pathNodeArray[CalculateIndex(1, 0, gridSize.x)]; // walkablePathNode.SetIsWalkable(false); // pathNodeArray[CalculateIndex(1, 0, gridSize.x)] = walkablePathNode; // walkablePathNode = pathNodeArray[CalculateIndex(1, 1, gridSize.x)]; // walkablePathNode.SetIsWalkable(false); // pathNodeArray[CalculateIndex(1, 1, gridSize.x)] = walkablePathNode; // walkablePathNode = pathNodeArray[CalculateIndex(1, 2, gridSize.x)]; // walkablePathNode.SetIsWalkable(false); // pathNodeArray[CalculateIndex(1, 2, gridSize.x)] = walkablePathNode; // // burst incompatible // NativeArray<int2> neighbourOffsetArray = new NativeArray<int2>(new int2[] { // new int2(-1, 0), // L // new int2(+1, 0), // R // new int2(0, -1), // D // new int2(0, +1), // U // new int2(-1, -1), // LD // new int2(-1, +1), // LU // new int2(+1, -1), // RD // new int2(+1, +1), // DU // }, Allocator.Temp); // burst compatible NativeArray <int2> neighbourOffsetArray = new NativeArray <int2>(8, Allocator.Temp); neighbourOffsetArray[0] = new int2(-1, 0); // L neighbourOffsetArray[1] = new int2(+1, 0); // R neighbourOffsetArray[2] = new int2(0, -1); // D neighbourOffsetArray[3] = new int2(0, +1); // U neighbourOffsetArray[4] = new int2(-1, -1); // LD neighbourOffsetArray[5] = new int2(-1, +1); // LU neighbourOffsetArray[6] = new int2(+1, -1); // RD neighbourOffsetArray[7] = new int2(+1, +1); // DU int endNodeIndex = CalculateIndex(endPosition.x, endPosition.y, size.x); PathNode startNode = pathNodeArray[CalculateIndex(startPosition.x, startPosition.y, size.x)]; startNode.costG = 0; startNode.CalculateCostF(); pathNodeArray[startNode.index] = startNode; NativeList <int> listOpen = new NativeList <int>(Allocator.Temp); NativeList <int> listClosed = new NativeList <int>(Allocator.Temp); listOpen.Add(startNode.index); while (listOpen.Length > 0) { int currentNodeIndex = GetLowestCostFNodeIndex(listOpen, pathNodeArray); PathNode currentNode = pathNodeArray[currentNodeIndex]; if (currentNodeIndex == endNodeIndex) { // reached end break; } // remove current node from open list for (int i = 0; i < listOpen.Length; i++) { if (listOpen[i] == currentNodeIndex) { listOpen.RemoveAtSwapBack(i); break; } } listClosed.Add(currentNodeIndex); for (int i = 0; i < neighbourOffsetArray.Length; i++) { int2 neighbourOffset = neighbourOffsetArray[i]; int2 neighbourPosition = new int2(currentNode.x + neighbourOffset.x, currentNode.y + neighbourOffset.y); if (!IsPositionInsideGrid(neighbourPosition, size)) { // neighbour not valid position continue; } int neighbourNodeIndex = CalculateIndex(neighbourPosition.x, neighbourPosition.y, size.x); if (listClosed.Contains(neighbourNodeIndex)) { // already searched this node continue; } PathNode neighbourNode = pathNodeArray[neighbourNodeIndex]; if (!neighbourNode.isWalkable) { // not walkable continue; } // diagonal neighbour if (Mathf.Abs(neighbourOffset[0]) + Mathf.Abs(neighbourOffset[1]) > 1) { // corners blocked if (!(pathNodeArray[CalculateIndex(neighbourPosition.x, currentNode.y, size.x)].isWalkable || pathNodeArray[CalculateIndex(currentNode.x, neighbourPosition.y, size.x)].isWalkable)) { continue; } } int2 currentNodePosition = new int2(currentNode.x, currentNode.y); int tentativeCostG = currentNode.costG + CalculateDistanceCost(currentNodePosition, neighbourPosition) + neighbourNode.weight; // if (tentativeCostG < neighbourNode.costG) if (tentativeCostG < neighbourNode.costG || !listOpen.Contains(neighbourNodeIndex)) { neighbourNode.indexPrev = currentNodeIndex; neighbourNode.costG = tentativeCostG; neighbourNode.CalculateCostF(); pathNodeArray[neighbourNodeIndex] = neighbourNode; if (!listOpen.Contains(neighbourNode.index)) { listOpen.Add(neighbourNode.index); } } } } PathNode endNode = pathNodeArray[endNodeIndex]; if (endNode.indexPrev == -1) { // path NOT found // print("het"); } else { // path found // path = PathCalculate(pathNodeArray, endNode); PathCalculate(pathNodeArray, endNode); // NativeList<int2> path = PathCalculate(pathNodeArray, endNode); // // * testing // foreach (int2 pathPosition in path) // { // Debug.Log(pathPosition); // } // path.Dispose(); } neighbourOffsetArray.Dispose(); listOpen.Dispose(); listClosed.Dispose(); }