예제 #1
0
        private static bool DrawSubGridHandle(SubGrid subGrid, SubGrid activeSubGrid, Color subGridColor)
        {
            Vector2Int subGridOriginPosition = subGrid.GetOriginCoordinate();
            Vector3    subGridWorldPosition  = subGrid.GetNavGrid().GetOriginWorldPosition() + new Vector3(subGridOriginPosition.x, 0, subGridOriginPosition.y);

            Vector3[] vertexs =
            {
                subGridWorldPosition,                                                 //Bottom-Left
                subGridWorldPosition + new Vector3(subGrid.Width, 0, 0),              //Bottom-Right

                subGridWorldPosition + new Vector3(subGrid.Width, 0, subGrid.Height), //Top-Right
                subGridWorldPosition + new Vector3(0,             0, subGrid.Height)  //Top-Left
            };

            Handles.DrawSolidRectangleWithOutline(vertexs, subGridColor, Color.black);

            if (subGrid.Equals(activeSubGrid))
            {
                return(false);
            }

            float centerX = vertexs[0].x + ((vertexs[1].x - vertexs[0].x) / 2f);
            float centerZ = vertexs[0].z + ((vertexs[3].z - vertexs[0].z) / 2f);

            Vector3 centerPosition = new Vector3(centerX, vertexs[0].y, centerZ);

            float buttonSize = 6f;

            if (Handles.Button(centerPosition, Quaternion.LookRotation(Vector3.up), buttonSize, buttonSize, Handles.RectangleHandleCap))
            {
                return(true);
            }
            return(false);
        }
예제 #2
0
        private static void HandleNodeClick(SubGrid subGrid, Vector2Int nodeCoordinates)
        {
            //Get the active instance of NavGridTool and send it the NodeClick
            NavGridTool navGridTool = (EditorWindow.GetWindow(typeof(NavGridTool)) as NavGridTool);

            navGridTool.HandleNodeClick(nodeCoordinates);
        }
예제 #3
0
        public void DrawSubGrid(NavGridTool tool)
        {
            if (currentMode != Mode.EDIT)
            {
                return;
            }



            SubGrid selectedSubGrid = tool.SelectedSubGrid;

            List <SubGrid> subGrids = selectedSubGrid.GetChildSubGrids();

            //If the current SubGrid has child SubGrids
            if (subGrids.Count > 0)
            {
                DrawSubGridHandle(selectedSubGrid, selectedSubGrid, SUBGRID_COLOR);

                for (int i = 0; i < subGrids.Count; i++)
                {
                    if (DrawSubGridHandle(subGrids[i], selectedSubGrid, SUBGRID_COLOR))
                    {
                        tool.SelectChildSubGrid(i);
                        return;
                    }
                }
            }
            else
            {
                DrawNodeHandles(tool, selectedSubGrid);
            }
        }
예제 #4
0
        //Splits the NavGrid into SubGrids for display purposes
        //This is needed as drawing too many Handles at once slows down the editor
        public static SubGrid CreateSubGrids(NavGrid navGrid, int nodeRenderLimit)
        {
            SubGrid primarySubGrid = new SubGrid(navGrid, null, new Vector2Int(), navGrid.Width, navGrid.Height);

            GenerateSubGrids(primarySubGrid, navGrid, nodeRenderLimit);

            return(primarySubGrid);
        }
예제 #5
0
 public void SelectChildSubGrid(int index)
 {
     if (index >= 0 && index < _selectedSubGrid.GetChildSubGrids().Count)
     {
         _selectedSubGrid = _selectedSubGrid.GetChildSubGrids()[index];
     }
     SceneView.RepaintAll();
 }
예제 #6
0
 public void RegenerateSubGrids()
 {
     if (currentNavGrid)
     {
         _selectedSubGrid = SubGridGenerator.CreateSubGrids(currentNavGrid, NODE_RENDER_LIMIT);
         _selectedNode    = NavGrid.NO_NODE;
         SceneView.RepaintAll();
     }
 }
예제 #7
0
        public SubGrid(NavGrid navGrid, SubGrid parent, Vector2Int originCoordinate, int width, int height)
        {
            this.navGrid = navGrid;
            this.parent  = parent;

            this.originCoordinate = originCoordinate;

            this.width  = width;
            this.height = height;

            subGrids = new List <SubGrid>();
        }
예제 #8
0
        //Divides the provided subgrid using the provided devisions
        private static List <SubGrid> DivideSubGrid(SubGrid currentSubGrid, NavGrid navGrid, Vector2 divisions)
        {
            int width  = currentSubGrid.Width;
            int height = currentSubGrid.Height;

            List <SubGrid> newSubGrids = new List <SubGrid>();

            float widthDivisions  = divisions.x;
            float heightDivisions = divisions.y;

            Vector2Int originCoordinate  = currentSubGrid.GetOriginCoordinate();
            Vector2Int currentCoordinate = originCoordinate;

            int xSize = Mathf.CeilToInt(width / widthDivisions);
            int ySize = Mathf.CeilToInt(height / heightDivisions);

            for (int y = 0; y < heightDivisions; y++)
            {
                //Correct ySize on the final row
                if (y == heightDivisions - 1)
                {
                    ySize = height - Mathf.RoundToInt(currentCoordinate.y - originCoordinate.y);
                }

                currentCoordinate.x = originCoordinate.x;
                for (int x = 0; x < widthDivisions; x++)
                {
                    SubGrid newSubGrid;

                    //Correct xSize on the final column
                    if (x == widthDivisions - 1)
                    {
                        newSubGrid = new SubGrid(navGrid, currentSubGrid, currentCoordinate, width - Mathf.RoundToInt(currentCoordinate.x - originCoordinate.x), ySize);
                    }
                    else
                    {
                        newSubGrid = new SubGrid(navGrid, currentSubGrid, currentCoordinate, xSize, ySize);
                    }

                    currentSubGrid.AddChildSubGrid(newSubGrid);
                    newSubGrids.Add(newSubGrid);

                    currentCoordinate.x += xSize;
                }

                currentCoordinate.y += ySize;
            }

            return(newSubGrids);
        }
예제 #9
0
        //Calculates how many times each side of the grid will be divided
        private static Vector2 CalculateGridDivisions(SubGrid subGrid, int targetNumberOfSections, int maxHandlesPerFrame)
        {
            int width  = subGrid.Width;
            int height = subGrid.Height;

            //If we only need 2 sections, divide the longest side
            if (targetNumberOfSections == 2)
            {
                if (width > height)
                {
                    return(new Vector2(2, 1));
                }
                else
                {
                    return(new Vector2(1, 2));
                }
            }
            else
            {
                Vector2 gridDivisions = new Vector2();
                int     divisor       = Mathf.CeilToInt(Mathf.Sqrt(targetNumberOfSections));

                //Calculate the shortest side first
                if (width < height)
                {
                    gridDivisions.x = CalculateSideDivisions(width, divisor, maxHandlesPerFrame);

                    //Calculate how many divisions are needed for the other side
                    if (gridDivisions.x != divisor)
                    {
                        divisor = Mathf.CeilToInt((targetNumberOfSections / (float)gridDivisions.x));
                    }
                    gridDivisions.y = Mathf.CeilToInt(targetNumberOfSections / gridDivisions.x);
                }
                else
                {
                    gridDivisions.y = CalculateSideDivisions(height, divisor, maxHandlesPerFrame);

                    //Calculate how many divisions are needed for the other side
                    if (gridDivisions.y != divisor)
                    {
                        divisor = Mathf.CeilToInt((targetNumberOfSections / (float)gridDivisions.y));
                    }
                    gridDivisions.x = Mathf.CeilToInt(targetNumberOfSections / gridDivisions.y);
                }

                return(gridDivisions);
            }
        }
예제 #10
0
        public void CreateSubGridAtSelection()
        {
            if (SelectedNode.Equals(NavGrid.NO_NODE))
            {
                return;
            }

            Vector2Int point = _selectedNode;

            point.x = Mathf.Clamp(point.x - (_selectedSubGrid.Width / 2), 0, currentNavGrid.Width - 1);
            point.y = Mathf.Clamp(point.y - (_selectedSubGrid.Height / 2), 0, currentNavGrid.Height - 1);

            _selectedSubGrid = SubGridGenerator.CreateSubGridAtPoint(currentNavGrid, _selectedSubGrid, point, _NODE_RENDER_LIMIT);
            SceneView.RepaintAll();
        }
예제 #11
0
        public void SelectParentSubGrid()
        {
            if (_selectedSubGrid == null || _selectedSubGrid.GetParentSubGrid() == null)
            {
                return;
            }

            SubGrid parentSubGrid = _selectedSubGrid.GetParentSubGrid();

            if (parentSubGrid != null)
            {
                _selectedSubGrid = parentSubGrid;
            }
            SceneView.RepaintAll();
        }
예제 #12
0
        //Fires when the active scene object changes
        private void OnSelectionChange()
        {
            currentNavGrid = FindSelectedNavGrid();

            if (currentNavGrid)
            {
                SceneView.onSceneGUIDelegate -= OnSceneGUI;
                SceneView.onSceneGUIDelegate += OnSceneGUI;

                _selectedSubGrid = SubGridGenerator.CreateSubGrids(currentNavGrid, NODE_RENDER_LIMIT);
            }
            else
            {
                SceneView.onSceneGUIDelegate -= OnSceneGUI;
            }
        }
예제 #13
0
        public static SubGrid CreateSubGridAtPoint(NavGrid navgrid, SubGrid currentSubgrid, Vector2Int point, int nodeRenderLimit)
        {
            int width  = Mathf.FloorToInt(Mathf.Sqrt(nodeRenderLimit));
            int height = width;

            if (navgrid.Width < point.x + width)
            {
                width = navgrid.Width - point.x;
            }
            if (navgrid.Height < point.y + height)
            {
                height = navgrid.Height - point.y;
            }

            SubGrid newSubGrid = new SubGrid(navgrid, currentSubgrid, point, width, height);

            return(newSubGrid);
        }
예제 #14
0
        //Recursively divides the provided subgrid into smaller subgrids until acceptable sizes are reached
        private static void GenerateSubGrids(SubGrid subGrid, NavGrid navGrid, int maxHandlesPerFrame)
        {
            //Determine how many sections we will be dividing into
            int numberOfSections = CalculateTargetNumberOfSections(subGrid, maxHandlesPerFrame);

            if (numberOfSections == 1)
            {
                return;
            }

            //Calculate how we will be dividing the grid, avoiding creating side lengths that are too small
            Vector2 gridDivisors = CalculateGridDivisions(subGrid, numberOfSections, maxHandlesPerFrame);

            //Divide the grid into SubGrids
            List <SubGrid> newSubGrids = DivideSubGrid(subGrid, navGrid, gridDivisors);

            //Divide each newly generated SubGrid
            foreach (SubGrid newSubGrid in newSubGrids)
            {
                GenerateSubGrids(newSubGrid, navGrid, maxHandlesPerFrame);
            }
        }
예제 #15
0
        //Calculate how many sections the grid should be divided into
        private static int CalculateTargetNumberOfSections(SubGrid subGrid, int maxHandlesPerFrame)
        {
            float targetAmount = (subGrid.Width * subGrid.Height) / (float)maxHandlesPerFrame;

            if (targetAmount <= 1f)
            {
                return(1);
            }

            if (targetAmount <= 2f)
            {
                return(2);
            }

            if (targetAmount <= 4)
            {
                return(4);
            }

            if (targetAmount <= 9f)
            {
                return(9);
            }

            if (targetAmount <= 16f)
            {
                return(16);
            }

            if (targetAmount <= 25f)
            {
                return(25);
            }

            return(36);
        }
예제 #16
0
        private void DrawNodeHandles(NavGridTool tool, SubGrid subGrid)
        {
            float NODE_SIZE = 0.45f;

            NavGrid navGrid = subGrid.GetNavGrid();

            Vector2Int subGridOriginPosition = subGrid.GetOriginCoordinate();
            Vector3    subGridWorldPosition  = navGrid.GetOriginWorldPosition() + new Vector3(subGridOriginPosition.x, 0, subGridOriginPosition.y);

            int width  = subGrid.Width;
            int height = subGrid.Height;

            //Draw each node
            for (int y = 0; y < height; y++)
            {
                for (int x = 0; x < width; x++)
                {
                    Vector2Int nodeCoordinates =
                        new Vector2Int(
                            subGridOriginPosition.x + x,
                            subGridOriginPosition.y + y
                            );

                    Handles.color = tool.ChooseNodeColor(nodeCoordinates);

                    if (currentMode == Mode.EDIT)
                    {
                        //Draw nodes as buttons and watch for input
                        if (Handles.Button(subGridWorldPosition + new Vector3(x, 0, y), Quaternion.LookRotation(Vector3.up), NODE_SIZE, NODE_SIZE, Handles.CubeHandleCap))
                        {
                            HandleNodeClick(subGrid, nodeCoordinates);
                        }
                    }
                }
            }
        }
예제 #17
0
 public void AddChildSubGrid(SubGrid newGrid)
 {
     subGrids.Add(newGrid);
 }