Exemple #1
0
 //BEGIN PATHFINDING Инициализация при клике на клетку (используется в MG_KeyboardMouseControl)
 public void InitCellForPathfinding(MG_hexagonCell selected_compCell)
 {
     if (GetComponent <MG_PathfindingModeGUI>().CheckBox_A_point)
     {
         SetCell_StartPoint(selected_compCell);                                                        //Режим: Установить Стартовую точку
     }
     if (GetComponent <MG_PathfindingModeGUI>().CheckBox_B_point)
     {
         SetCell_TargetPoint(selected_compCell);                                                        //Режим: Установить Цель точку
     }
 }
    private Collection <MG_AP_PathNode> GetNeighbours(MG_AP_PathNode pathNode,
                                                      MG_hexagonCell goal)
    {
        Step++;
        var result = new Collection <MG_AP_PathNode>();

        // Соседними точками являются соседние по стороне клетки.
        MG_hexagonCell[] neighbourPoints = new MG_hexagonCell[6];
        neighbourPoints[0] = pathNode.Current_compCell.NeighbourArray[0];
        neighbourPoints[1] = pathNode.Current_compCell.NeighbourArray[1];
        neighbourPoints[2] = pathNode.Current_compCell.NeighbourArray[2];
        neighbourPoints[3] = pathNode.Current_compCell.NeighbourArray[3];
        neighbourPoints[4] = pathNode.Current_compCell.NeighbourArray[4];
        neighbourPoints[5] = pathNode.Current_compCell.NeighbourArray[5];
        foreach (var neighbour in neighbourPoints)
        {
            if (!neighbour)//если существует соседняя клетка
            {
                continue;
            }
            if (!neighbour.Walkable)//если можно ходить по ней
            {
                continue;
            }

            // Заполняем данные для точки маршрута.
            TotalVisitedCells++;
            if (TotalVisitedCells == TotalCellcount)//если слишком много шагов, то перестать искать!
            {
                continue;
            }

            GameObject obj_pathNode = Instantiate(Prefab_pathNode);                                                                                          //Создание нода
            obj_pathNode.transform.parent = this.transform;                                                                                                  //Вставляем данный child в Parent
            obj_pathNode.name             = "Pathnode №" + TotalVisitedCells + ": (" + neighbour.GameCoordinate_x + ", " + neighbour.GameCoordinate_y + ")"; //Задаем имя объекту

            MG_AP_PathNode neighbourNode = obj_pathNode.GetComponent <MG_AP_PathNode>();
            ArrayOfNodes[TotalVisitedCells]           = neighbourNode;//кладем в массив
            neighbourNode.Position                    = neighbour.transform;
            neighbourNode.CameFrom                    = pathNode;
            neighbourNode.PathLengthFromStart         = pathNode.PathLengthFromStart + 1;// neighbourNode.GetDistanceBetweenNeighbours();
            neighbourNode.HeuristicEstimatePathLength = GetHeuristicPathLength(neighbour, goal);
            neighbourNode.Current_compCell            = neighbour;

            result.Add(neighbourNode);
            neighbour.Rend.material.color = Color.magenta;
            //neighbour.Label.text = "" + Step + "";
        }
        return(result);
    }
    public void ButtonPressed_Start()
    {
        //GetComponent<MG_Pathfinding>().Start_Pathfinding(); //OLD

        MG_hexagonCell start = GetComponent <MG_Pathfinding>().Comp_StartCell;
        MG_hexagonCell end   = GetComponent <MG_Pathfinding>().Comp_TargetCell;

        if (start && end)
        {
            List <MG_hexagonCell> way = GetComponent <MG_AP_Pathfinding>().FindPath(start, end);
        }
        else
        {
            Debug.LogWarning("ButtonPressed_Start(): Не задана начальная или контрольная точка!");
        }
    }
Exemple #4
0
    //END PATHFINDING Назначаем начальную точку

    //BEGIN PATHFINDING Назначаем начальную точку
    public void SetCell_TargetPoint(MG_hexagonCell selected_compCell)
    {
        //BEGIN предыдущую цель нужно перекрасить в обычный цвет
        MG_hexagonCell comp_previousTargetCell = GetComponent <MG_Pathfinding>().Comp_TargetCell;// берем предыдущий заданный объект цели

        if (comp_previousTargetCell)
        {
            comp_previousTargetCell.GetComponent <MG_hexagonCell>().CancelSelect();// если предыдущий объект был задан, то нужно ресетнуть цвет.
            //obj_previousTargetCell.GetComponent<MG_hexagonCell>().IsSelectedByMouse = false;// Чтобы можно было перекрасить при заходе мышкой
        }
        //END предыдущую цель нужно перекрасить в обычный цвет

        selected_compCell.GetComponent <MG_hexagonCell>().IsSelectedByMouse   = true;                        //Кликнута мышкой, иначе цвет при наведении перезальется
        selected_compCell.GetComponent <MG_hexagonCell>().Rend.material.color = new Color(0.2F, 0.3F, 0.4F); //ORANGE Задаем новый цвет клетки цели
        selected_compCell.Walkable = true;
        GetComponent <MG_Pathfinding>().Comp_TargetCell = selected_compCell;                                 //Задаем скрипту MG_Pathfinding объект цели
    }
 private float GetHeuristicPathLength(MG_hexagonCell from, MG_hexagonCell to)
 {
     return(Math.Abs(from.transform.position.x - to.transform.position.x) + Math.Abs(from.transform.position.y - to.transform.position.y));
 }
    public List <MG_hexagonCell> FindPath(MG_hexagonCell start, MG_hexagonCell goal)
    {
        //Шаг 0. ПОДГОТОВКА
        RemoveAllNodes();


        // Шаг 1.
        Debug.Log("FindPath(): Шаг 1.");
        var closedSet = new Collection <MG_AP_PathNode>();
        var openSet   = new Collection <MG_AP_PathNode>();

        TotalVisitedCells = 0;
        Step = 0;
        // Шаг 2.
        Debug.Log("FindPath(): Шаг 2.");
        GameObject obj_pathNode = Instantiate(Prefab_pathNode);                                                                                  //Создание нода

        obj_pathNode.transform.parent = this.transform;                                                                                          //Вставляем данный child в Parent
        obj_pathNode.name             = "Pathnode №" + TotalVisitedCells + ": (" + start.GameCoordinate_x + ", " + start.GameCoordinate_y + ")"; //Задаем имя объекту

        MG_AP_PathNode startNode = obj_pathNode.GetComponent <MG_AP_PathNode>();

        start.Label.text = "" + Step + "";
        ArrayOfNodes[TotalVisitedCells] = startNode;//кладем в массив
        startNode.Position                    = start.transform;
        startNode.CameFrom                    = null;
        startNode.PathLengthFromStart         = 0;
        startNode.HeuristicEstimatePathLength = GetHeuristicPathLength(start, goal);
        startNode.Current_compCell            = start;

        openSet.Add(startNode);
        while (openSet.Count > 0)
        {
            // Шаг 3.
            Debug.Log("FindPath(): Шаг 3.");
            var currentNode = openSet.OrderBy(node =>
                                              node.EstimateFullPathLength).First();
            // Шаг 4.
            Debug.Log("FindPath(): Шаг 4.");
            if (currentNode.Current_compCell == goal)
            {
                List <MG_hexagonCell> listOfCells = GetPathForNode(currentNode);
                ReColorPatch(listOfCells);
                start.Rend.material.color = Color.green;
                goal.Rend.material.color  = new Color(0.2F, 0.3F, 0.4F);
                start.Label.text          = "->BEGIN<-";
                goal.Label.text           = "->GOAL<-";
                return(listOfCells);
            }

            // Шаг 5.
            Debug.Log("FindPath(): Шаг 5.");
            openSet.Remove(currentNode);
            closedSet.Add(currentNode);
            // Шаг 6.
            Debug.Log("FindPath(): Шаг 6.");
            foreach (var neighbourNode in GetNeighbours(currentNode, goal))
            {
                // Шаг 7.
                Debug.Log("FindPath(): Шаг 7.");
                if (closedSet.Count(node => node.Position == neighbourNode.Position) > 0)
                {
                    continue;
                }
                var openNode = openSet.FirstOrDefault(node =>
                                                      node.Position == neighbourNode.Position);
                // Шаг 8.
                Debug.Log("FindPath(): Шаг 8.");
                if (openNode == null)
                {
                    openSet.Add(neighbourNode);
                }
                else
                if (openNode.PathLengthFromStart > neighbourNode.PathLengthFromStart)
                {
                    // Шаг 9.
                    Debug.Log("FindPath(): Шаг 9.");
                    openNode.CameFrom            = currentNode;
                    openNode.PathLengthFromStart = neighbourNode.PathLengthFromStart;
                }
            }
        }
        // Шаг 10.
        Debug.LogWarning("FindPath(): Шаг 10. Путь не найден!");

        return(null);
    }
    //END Используется в MG_KeyboardMouseControl для изменения цвета клетки после клика


    public void SetNeigbrours()
    {
        NeighbourArray = new MG_hexagonCell[6];

        int x_plus  = gameCoordinate_x + 1;
        int x_minus = gameCoordinate_x - 1;

        int y_plus  = gameCoordinate_y + 1;
        int y_minus = gameCoordinate_y - 1;

        bool NotoutOfRange_x_plus  = (GridCell.X > x_plus);
        bool NotoutOfRange_x_minus = (0 <= x_minus);

        bool NotoutOfRange_y_plus  = (GridCell.Y > y_plus);
        bool NotoutOfRange_y_minus = (0 <= y_minus);



        if (FlatTopped)
        {
            if (CoordStyle_isVar1)
            {
                if (NotoutOfRange_x_minus)
                {
                    NeighbourArray[0] = GridCell.ArrayOfCells_2D[gameCoordinate_x - 1, gameCoordinate_y];
                }

                if (NotoutOfRange_x_minus && NotoutOfRange_y_plus)
                {
                    NeighbourArray[1] = GridCell.ArrayOfCells_2D[gameCoordinate_x - 1, gameCoordinate_y + 1];
                }

                if (NotoutOfRange_y_plus)
                {
                    NeighbourArray[2] = GridCell.ArrayOfCells_2D[gameCoordinate_x, gameCoordinate_y + 1];
                }

                if (NotoutOfRange_x_plus)
                {
                    NeighbourArray[3] = GridCell.ArrayOfCells_2D[gameCoordinate_x + 1, gameCoordinate_y];
                }

                if (NotoutOfRange_y_minus)
                {
                    NeighbourArray[4] = GridCell.ArrayOfCells_2D[gameCoordinate_x, gameCoordinate_y - 1];
                }

                if (NotoutOfRange_x_minus && NotoutOfRange_y_minus)
                {
                    NeighbourArray[5] = GridCell.ArrayOfCells_2D[gameCoordinate_x - 1, gameCoordinate_y - 1];
                }
            }
            else
            {
                if (NotoutOfRange_x_minus)
                {
                    NeighbourArray[0] = GridCell.ArrayOfCells_2D[gameCoordinate_x - 1, gameCoordinate_y];
                }

                if (NotoutOfRange_y_plus)
                {
                    NeighbourArray[1] = GridCell.ArrayOfCells_2D[gameCoordinate_x, gameCoordinate_y + 1];
                }

                if (NotoutOfRange_x_plus && NotoutOfRange_y_plus)
                {
                    NeighbourArray[2] = GridCell.ArrayOfCells_2D[gameCoordinate_x + 1, gameCoordinate_y + 1];
                }

                if (NotoutOfRange_x_plus)
                {
                    NeighbourArray[3] = GridCell.ArrayOfCells_2D[gameCoordinate_x + 1, gameCoordinate_y];
                }

                if (NotoutOfRange_x_plus && NotoutOfRange_y_minus)
                {
                    NeighbourArray[4] = GridCell.ArrayOfCells_2D[gameCoordinate_x + 1, gameCoordinate_y - 1];
                }

                if (NotoutOfRange_y_minus)
                {
                    NeighbourArray[5] = GridCell.ArrayOfCells_2D[gameCoordinate_x, gameCoordinate_y - 1];
                }
            }
        }
        else
        {
            if (CoordStyle_isVar1)
            {
                if (NotoutOfRange_x_minus && NotoutOfRange_y_minus)
                {
                    NeighbourArray[0] = GridCell.ArrayOfCells_2D[gameCoordinate_x - 1, gameCoordinate_y - 1];
                }

                if (NotoutOfRange_x_minus)
                {
                    NeighbourArray[1] = GridCell.ArrayOfCells_2D[gameCoordinate_x - 1, gameCoordinate_y];
                }

                if (NotoutOfRange_y_plus)
                {
                    NeighbourArray[2] = GridCell.ArrayOfCells_2D[gameCoordinate_x, gameCoordinate_y + 1];
                }

                if (NotoutOfRange_x_plus)
                {
                    NeighbourArray[3] = GridCell.ArrayOfCells_2D[gameCoordinate_x + 1, gameCoordinate_y];
                }

                if (NotoutOfRange_x_plus && NotoutOfRange_y_minus)
                {
                    NeighbourArray[4] = GridCell.ArrayOfCells_2D[gameCoordinate_x + 1, gameCoordinate_y - 1];
                }

                if (NotoutOfRange_y_minus)
                {
                    NeighbourArray[5] = GridCell.ArrayOfCells_2D[gameCoordinate_x, gameCoordinate_y - 1];
                }
            }
            else
            {
                if (NotoutOfRange_x_minus)
                {
                    NeighbourArray[0] = GridCell.ArrayOfCells_2D[gameCoordinate_x - 1, gameCoordinate_y];
                }

                if (NotoutOfRange_x_minus && NotoutOfRange_y_plus)
                {
                    NeighbourArray[1] = GridCell.ArrayOfCells_2D[gameCoordinate_x - 1, gameCoordinate_y + 1];
                }

                if (NotoutOfRange_y_plus)
                {
                    NeighbourArray[2] = GridCell.ArrayOfCells_2D[gameCoordinate_x, gameCoordinate_y + 1];
                }

                if (NotoutOfRange_x_plus && NotoutOfRange_y_plus)
                {
                    NeighbourArray[3] = GridCell.ArrayOfCells_2D[gameCoordinate_x + 1, gameCoordinate_y + 1];
                }

                if (NotoutOfRange_x_plus)
                {
                    NeighbourArray[4] = GridCell.ArrayOfCells_2D[gameCoordinate_x + 1, gameCoordinate_y];
                }

                if (NotoutOfRange_y_minus)
                {
                    NeighbourArray[5] = GridCell.ArrayOfCells_2D[gameCoordinate_x, gameCoordinate_y - 1];
                }
            }
        }
    }
    //BEGIN ДЛЯ ТЕСТА, ЧТОБЫ ПЕРЕСОЗДАТЬ КАРТУ И ПОЛУЧИТЬ НЕ ПУСТЫЕ ПЕРЕМЕННЫЕ.


    public void GenerateGrid()                          //Создано для одного типа Hexagonal cell: Pointy Topped (другой Flat Topped возможен!)
    {
        GridCanvas = GetComponentInChildren <Canvas>(); //Canvas для текста
        float x_Pos    = 0;                             //Позиция по горизонтали для новой клетки
        float y_Pos    = 0;                             //Позиция по вертикали для новой клетки
        int   xy_fixer = 0;                             //Коррекция для правильной Hexagon карты (Значение: 0-1), чтобы выглядила как квадратная карта.

        //BEGIN Если выбран тип карты FlatToppe
        if (FlatTopped)
        {
            SelectedHexagonPrefab = HexFlatToppe;
        }
        else
        {
            SelectedHexagonPrefab = HexPointyTopped;
        }
        //END Если выбран тип карты FlatToppe, а не PointyTopped
        ArrayOfCells_2D = new MG_hexagonCell[Y, X];

        //BEGIN Default настрйоки для изменения типа карты, иначе будут глюки
        this.transform.eulerAngles = new Vector3(0, 0, 0);
        this.transform.position    = new Vector3(0, 0, 0);
        //END Default настрйоки для изменения типа карты, иначе будут глюки

        for (int i = 0; i < Y; i++)
        {
            if (FlatTopped)
            {
                x_Pos    = 0;                   //Для создания правильной квадратной карты  с Hex
                y_Pos    = 0 + (-5f) * (i - 1); // + (-5f) * (i - 1);//(y_Pos + - 5f) * (i-1);//Для создания правильной квадратной карты  с Hex (след строка)
                xy_fixer = 0;
            }
            else
            {
                x_Pos = 2.5f * xy_fixer;  //Для создания правильной квадратной карты  с Hex
                y_Pos = 4.25f * i * (-1); //Для создания правильной квадратной карты  с Hex (след строка)
            }

            for (int j = 0; j < X; j++)
            {
                this.transform.localScale = new Vector3(1, 1, 1);//Scale самой карты (можно поменять в конце метода если необходимо)

                //BEGIN Создание клетки объекта и его настройка
                GameObject hexagon = Instantiate(SelectedHexagonPrefab);                               //Создание самой клетки
                ArrayOfCells_2D[i, j]        = hexagon.GetComponent <MG_hexagonCell>();                //кладем в массив
                hexagon.transform.parent     = this.transform;                                         //Вставляем данный child в Parent
                hexagon.transform.position   = new Vector3(x_Pos, y_Pos, 0);                           //позиция клетки на карте
                hexagon.transform.localScale = new Vector3(1, 1, 1);                                   //масштаб клетки

                hexagon.GetComponent <MG_hexagonCell>().GameCoordinate_x = i;                          //Задаем игровую координату по X
                hexagon.GetComponent <MG_hexagonCell>().GameCoordinate_y = j;                          //Задаем игровую координату по Y
                hexagon.GetComponent <MG_hexagonCell>().EditorCoordinate = hexagon.transform.position; //Задаем реальную позицию в редакторе
                hexagon.GetComponent <MG_hexagonCell>().GridCell         = this;                       //Назначаем саму карту
                hexagon.GetComponent <MG_hexagonCell>().FlatTopped       = FlatTopped;                 //Вид Hexagon
                hexagon.GetComponent <MG_hexagonCell>().Walkable         = true;                       //Можно ли ходить (для PATHFINDING) 08.03.2018
                hexagon.name = "Hexagon (" + i + ", " + j + ")";                                       //Задаем имя объекту

                //-Для лучшего способа получение соседей, чтобы не перепрыгивать через соседа (тот самый баг для Хексагонов).
                if (xy_fixer == 0)
                {
                    hexagon.GetComponent <MG_hexagonCell>().CoordStyle_isVar1 = true;
                }
                else
                {
                    hexagon.GetComponent <MG_hexagonCell>().CoordStyle_isVar1 = false;
                }
                //-end

                //END Создание клетки объекта и его настройка

                //BEGIN Метка координатная на клетке
                Text label = Instantiate <Text>(CellLabelPrefab);           //Создание самой метки
                label.rectTransform.SetParent(GridCanvas.transform, false); //Задаем Parent
                label.rectTransform.anchoredPosition =                      //Задаем позицию
                                                       new Vector2(x_Pos, y_Pos);
                label.text = i + ", " + j;                                  //Задаем текст
                hexagon.GetComponent <MG_hexagonCell>().Label = label;      //Задаем клетки данный текст в память для будущей интеракции
                label.name = "Label (" + i + ", " + j + ")";                //Задаем имя объекту
                //END Метка координатная на клетке

                if (FlatTopped)
                {
                    x_Pos += 4.25f;//Корректировка для следующей клетки
                    if (xy_fixer == 0)
                    {
                        y_Pos   += -2.49f;//Корректировка для следующей клетки
                        xy_fixer = 1;
                    }
                    else
                    {
                        y_Pos   += 2.49f;//Корректировка для следующей клетки
                        xy_fixer = 0;
                    }
                }
                else
                {
                    x_Pos += 5f;//Корректировка для следующей клетки
                }
                //hexagon.GetComponent<Hexagon>().OffsetCoord = new Vector2(0, 0);
            }

            //BEGIN Специальная коррекция для Hexagon карты, чтобы выглядила как квадратная карта
            if (FlatTopped)
            {
                // y_Pos += -5f;
            }
            else
            {
                if (xy_fixer == 0)
                {
                    xy_fixer = 1;
                }
                else
                {
                    xy_fixer = 0;
                }
            }
            //END Специальная коррекция для Hexagon карты, чтобы выглядила как квадратная карта
        }

        SetAllNeigbroursForAllCell();//Для установки соседей для всех клеток после генерации карты
    }