public void Navigate(ShipRuntime targetShip, Vector2Int globalStartPos, Vector2Int globalEndPos) { Init(); this.targetShip = targetShip; if (globalStartPos == globalEndPos) { StartCoroutine("DelaySearch"); return; } nextIndex = 1; CellTemplate startCell = targetShip.GetCellByGlobalPos(globalStartPos); CellTemplate endCell = targetShip.GetCellByGlobalPos(globalEndPos); // Invalid path supplied if (startCell == null || endCell == null || startCell.CellState == 0 || endCell.CellState == 0) { return; } ShipPiece startPiece = targetShip.GetPieceByGlobalCellPos(globalStartPos); ShipPiece endPiece = targetShip.GetPieceByGlobalCellPos(globalEndPos); NavGrid startGrid = new NavGrid(startPiece); startGrid.Generate(); NavGrid goalGrid = startGrid; if (startPiece != endPiece) { goalGrid = new NavGrid(endPiece); goalGrid.Generate(); } AStarAlgorithm aStarAlgorithm = new AStarAlgorithm(startGrid, goalGrid, globalStartPos, globalEndPos); int newTTmp = 0; curPath = aStarAlgorithm.AStarSearch(ref newTTmp); wiggleTimer = Random.Range(0, 6.28318f); }
public bool Navigate(ShipRuntime targetShip, Vector2Int globalStartPos, Vector2Int globalEndPos) { if (globalStartPos == globalEndPos) { return(false); } NavCell[] overrideStart = null; // Cur, prev and T evaluation if (curPath != null) { if (nextIndex < curPath.Length) { overrideStart = new NavCell[2]; // Store C0 and C1 overrideStart[0] = curPath[nextIndex - 1]; overrideStart[1] = curPath[nextIndex]; } } nextIndex = 1; CellTemplate startCell = targetShip.GetCellByGlobalPos(globalStartPos); CellTemplate endCell = targetShip.GetCellByGlobalPos(globalEndPos); // Invalid path supplied if (startCell == null || endCell == null || startCell.CellState == 0 || endCell.CellState == 0) { return(false); } ShipPiece startPiece = targetShip.GetPieceByGlobalCellPos(globalStartPos); ShipPiece endPiece = targetShip.GetPieceByGlobalCellPos(globalEndPos); NavGrid startGrid = new NavGrid(startPiece); startGrid.Generate(); NavGrid goalGrid = startGrid; if (startPiece != endPiece) { goalGrid = new NavGrid(endPiece); goalGrid.Generate(); } AStarAlgorithm aStarAlgorithm = new AStarAlgorithm(startGrid, goalGrid, globalStartPos, globalEndPos); int newTState = -1; curPath = aStarAlgorithm.AStarSearch(ref newTState, overrideStart); // Either reset, invert or leave move timer switch (newTState) { case -1: moveTimer = 0; break; case 1: moveTimer = 1 - moveTimer; break; } pathTracer.SetPositions(GetNavArray()); return(curPath != null); }
public NavCell[] AStarSearch(ref int newTState, NavCell[] overrideStart = null) { openList.Clear(); closedList.Clear(); var startCell = grids[0].FindCellByPosition(start); var goalCell = grids[grids.Count - 1].FindCellByPosition(goal); startCell.heuristic = (goal - startCell.position).magnitude; openList.Add(startCell); int itterations = 0; while (openList.Count > 0) { itterations++; var bestCell = GetBestCell(); openList.Remove(bestCell); var neighbours = bestCell.OwningGrid.GetMooreNeighbours(bestCell); for (int i = 0; i < 4; i++) { var curCell = neighbours[i]; if (curCell == null) { bool connectionMade = false; if (bestCell.Cell.HasConnections) { Vector2Int compareDir = new Vector2Int(0, 1); switch (i) { case 1: compareDir = new Vector2Int(1, 0); break; case 2: compareDir = new Vector2Int(0, -1); break; case 3: compareDir = new Vector2Int(-1, 0); break; } // Collect new neighbours ShipConnection connection = bestCell.Cell.OwningPiece.GetConnectionByCellPos(bestCell.position, compareDir); if (connection != null) { connectionMade = true; // Attempt to locate existing grid NavGrid connectedGrid = null; foreach (NavGrid grid in grids) { if (connection.OtherPiece == grid.PieceCreatedFrom) { connectedGrid = grid; break; } } // Else Generate new grid from piece if (connectedGrid == null) { connectedGrid = new NavGrid(connection.OtherPiece); connectedGrid.Generate(); grids.Add(connectedGrid); } // Assign the cell on the other grid as the cur cell and continue pathfinding as normal curCell = connectedGrid.FindCellByPosition(connection.OtherCell + connection.OtherPiece.Position); } } if (!connectionMade) { continue; } } if (curCell == goalCell) { curCell.parent = bestCell; return(ConstructPath(curCell, ref newTState, overrideStart)); } // Cell / Wall state logic if (curCell.Cell.CellState == 0) // Cell state is 0 (piece does not contain this cell as walkable area). { // Add to closed and continue if (!closedList.Contains(curCell)) { closedList.Add(curCell); } continue; } var g = bestCell.cost + (curCell.position - bestCell.position).magnitude; var h = (goal - curCell.position).magnitude; if (openList.Contains(curCell) && curCell.f < (g + h)) { continue; } if (closedList.Contains(curCell) && curCell.f < (g + h)) { continue; } curCell.cost = g; curCell.heuristic = h; curCell.parent = bestCell; if (!openList.Contains(curCell)) { openList.Add(curCell); } } if (!closedList.Contains(bestCell)) { closedList.Add(bestCell); } if (itterations > 10000) { Debug.Log("MAX ITTERATIONS REACHED, NOT GOOD"); break; } } return(null); }