How To Get A Better Grid Layout in Unity

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
let's face it grids are an essential part of game UI design whether it's a main menu a puzzle layout an inventory screen or an item selection menu it's difficult to escape the need for a grid one of the design trends over the past few years has been to implement multi-platform menus through a tower based layout with different tabs and panels I'm a huge fan of this style and I specifically love seeing how different companies put their own take on it what's noticeable to me about many of these screens is how the number of tiles in each panel frequently varies and how the layout is adjusted to best fit the number of tiles on display in the previous video we looked at how we might be able to emulate these kind of menus by using color palettes and layout groups today we're going to pick up where we left off and look at how we can build our own tile based flexible menu system hi there I'm Matt and welcome to game dev guide in this video we're going to take a look at how we can build a multi-page panel system that can be switched through using tabs and then we're going to look at how we can build out our own grid layout component that automatically arranges its children and builds a grid layout based on the space available so we've got the first part of our front-end menu here we've got a canvas with a panel and the panel is split into two halves the top part here is going to be our tab area and the body will be the display for our tiles so let's get started and build out the tabs for our menu I'm going to be using a tab system similar to the one discussed in this video which means that I'm not going to go too much into detail about how those system works in this video I'll link it down below if you missed it or want a refresher on how it works I'm going to create a few different tabs here that we can flick through but to save myself a bit of work I'm gonna design the first one well first and then duplicate it once I'm done with for ease of design I'm going to just use a script here to grab the text from the name of the parent game object in a production scenario you'd probably pull this text from a localization system but this is a fine place holder for now and so this script stops me constantly fiddling around with various text components another important factor in UI design is picking a good font there are two types of fonts good fonts and then everything else take a look at the big budget games you might notice how most of them use really readable fonts and you might also notice how a lot of them look really similar to one another this is down to years and years of exposure for us of basically five to six different types of fonts my suggestion to make something look good is to stick to a common font and stick to one or two throughout your entire UI don't try to reinvent the wheel there's a reason we see the same fonts everywhere much like with the color palettes discussed in the last video consistency is key so be sure to make some rules for yourself and stick to them a good rule for Tech's design that I like to abide by is have one font and wait for headers such as a bold or heavy weight perhaps in uppercase and then another weight of the same font for general prose text I'm a big fan of Futura and I picked up future RPT a while ago unless the design cause otherwise this is a baseline font for all of my projects so we'll just go ahead here and create a font a set and now we've got some fonts to work with I'm going to assign the heavy font here and set it all to uppercase and the tab settings I'll assign the image graphic and the text graphic and set the active and inactive colors and of course assign it to our tab group now let's duplicate this out and name the rest of our tabs like so this is looking pretty good I want to emulate a bit of cross-platform support so I'm actually going to add these lines here to switch tabs back and forth miss Pacific key is pressed it's probably a whole other video I could do on input systems and multi-platform stuff for now I'm just going to hard code it using Q and E I'm also going to restructure this bar a little bit to show the two functions in the menu here in fact let's swap the image from our main header here to slightly transparent black and round the edges using a sprite we've got our left and right in here now so we can add a slight gray divider between our tabs by spacing them out a bit and setting the image on our parent to be gray like so with that set up it's time to organize our body it's pretty common to want our tabs to control a series of pages or panels so instead of assigning that logic to each button or tab individually we can build a little panel controller script that interacts with our tab system and manages each panel enabling or disabling panels based on which tab is selected let's create a script called panel group at the top here let's expose an array of game objects to act as our panels then let's also expose the tab group that will be linked to our panels and we'll add an integer to store the index of are currently active page let's create a new method called show current panel which will call on awake and here we'll loop through the pages and disable anything that isn't our current page then let's create a method called set page index that will set the index our page and call our show current panel method and then back in our tab group all we need to do is make a reference to our panel group and when a tab is selected call our set page index method now I just need to make some children to our panel group here and then if we take a look whenever we select the tab in our panel group it enables the corresponding game object for that tab so we've got a tab logic working and we're ready to switch between pages which means that it's time to design our panels I think it's probably worth taking a moment to explain why I've ended up down this road and why if you're doing any kind of UI work in unity this video should hopefully save you a lot of pain let's just add a default grid component here and take a look at everything that sucks about it one of the biggest problems of this component is that it doesn't really behave like the other two the horizontal group and vertical groups fill their child elements to the size of that container but the grid component doesn't do that it requires a predefined input for fixed sizes of cells to set the children and then based on the space available just lays them out accordingly and this is okay I guess if you're designing an inventory screen or something but even then it's still lacking the fundamental features like Auto spacing to fill out the rect transform honestly it's just a really lackluster component and counterintuitive compared to how the other two work so what we're going to do is build out our own grid component that behaves more like we'd expect and like the horizontal or vertical components this grid component will get the number of children and based on our input settings figure out how best to size them to fill the space the end result will be an extremely adaptable and extremely flexible layout component that will make it simple and easy to build grid-based layouts let's create a new script called flexible grid layout we'll extend it from the layout group class and implement the interface let's have an integer at the top here for our rows and columns let's also add a vector2 to keep track of our cell size the default method called in the layout group is calculate layout input horizontal it's a little misleading for our purposes but we'll be putting all of our layout code in here first we'll calculate the number of rows and columns by finding the square root of the number of children in the transform next we'll get the width and height of our container so we know how much space were able to work with and then let's define a size for each of our children based off of the info we now have then we'll assign these values to the X&Y position of our cell size property then we'll create some variables to keep a count of our column and row indexes as we lay everything out in a for loop will iterate over all the children in the rect transform and we'll find our current row index and our current column index like so and then get a reference to our child object let's create a reference to an x and y position using the column and row counts multiplied by the width and height and then finally call the set child along axis method for each axis we've now got a system that lays out a grid relative to the number of children so this is a good start but there's a few issues we need to be able to add some spacing between the elements and we also need to be able to support padding around the edges at the top of our script let's add a new vector2 called spacing then let's add the spacing to the positioning code here this is okay but notice how when we add spacing to our component were actually just overflowing our elements here so what we want to do is reduce the width and height of each of our cells relative to the spacing we're adding so we're we're setting our cell width and height let's reduce both of these relative to our spacing now when we add the spacing the children remain contained within our transform next we just need to add the padding this will require a similar behavior to our spacing if we just offset the X&Y position of ourselves relative to the padding values or have the same problem where we're just shifting everything across so we need to reduce the width and height of ourselves relative to the padding values to now we should have a basic grid layout that fits uniformly and supports both spacing and padding awesome so already we've got what I would consider a more functional grid layout tool but I think we could do a little bit more to take it that a little bit further in functionality by adding a bit more flexibility for different types of layouts right now we're scaling uniformly based on the number of children we've always got the same number of columns and rows but let's also add support to prioritize one over the other let's create an enum in our script called fit type and define an entry for uniform width and height the idea here is that when we're uniform and setting our columns based on the square root of our grid we often end up with a lot of empty space after a certain number of children so we're picking a priority along the width or height of the transform we can actually make more use of the space to do this we just need to add a check for the current fit type and for our height divide the values by the rows or for our width divided by our number of columns now if we assign a fit type in the inspector and make sure we have a non-square amount of children a layout is much more adaptive but Onoda video we're not done just yet this can still be more useful automatic layouts are nice but there are obviously some screens that you're going to want to tile but have more control over perhaps you want to fill the space but you want to limit the grid to a fixed number of columns and just help the rows be generated automatically or perhaps you only want two rows and are happy implementing a horizontal scroll with your tiles overflowing in our script let's add two new entries to our fit type fixed rows and fixed columns let's also create a boolean for each axis called fit X and fit Y now we've got a few changes to make depending on these settings let's wrap our row and column calculations into an if statement to check that we're in one of these auto types and then that set the fit X and fit Y to true if any of these are enabled otherwise let's check if we're in fixed rows or fixed columns mode then we'll just set the rows and columns accordingly next we want to be able to have control over our cell size if we're in either of these new modes so when we're designating our cell width and height to our vector let's check if they're set to fit if they are we use the auto width and auto height layout with that we pretty much have an extremely multi-user layout component if we switch into our new fixed row or fixed column count it can even behave like the standard horizontal or vertical layout groups with all this pretty much laid out you might still be wondering how we'd go about splitting the layout up even more to get some variations of tile sizes much like the menus we've looked at as referenced it's pretty common to want variation like this as you may want to draw their players to a specific point in a menu or prioritize certain tiles over others originally I thought about creating some crazy functionality to adjust individual sizes and scales based on the elements on the children but eventually I realized that we can actually just double down on the component as you can see if we just treat it like a usual layout group and nest these components we can create more variation to the layout without any extra work as a final touch I've just added some tweening animations to my text and UI components here to give the menu a little bit of juice as we switch between the layouts overall I'm really happy with how well this has come together the script may or may not help you in your endeavors but as you can see from the menu we've built it's a hell of a lot more useful than the built in grid component I'm sure there's a lot more you can do with it and I encourage you to play around with the idea to see what kind of other layout features you can add and that's all from me for now let me know if this video has been helpful in the comments down below the last video kind of blew up and there's a hell of a lot more of you here now so awesome thank you I'm glad you're enjoying the videos that said the stats still showing me that there are 70% of you who are watching that aren't subscribed so you know who you are and you know what to do if you're interested in more videos from me perhaps try checking out some of the others on screen now but as always thank you very much for watching and I'll see you again next time
Info
Channel: Game Dev Guide
Views: 101,524
Rating: undefined out of 5
Keywords: unity, learn, games, gamedev, how to, making games in unity, tutorial, unity tutorial, learning unity, unity3d tutorial, programming, making games
Id: CGsEJToeXmA
Channel Id: undefined
Length: 12min 4sec (724 seconds)
Published: Tue Mar 24 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.