Ejemplo n.º 1
0
    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);
    }
Ejemplo n.º 3
0
    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);
    }