Grid System in Unity (Heatmap, Pathfinding, Building Area)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
in this video we're going to make a grid map to cut our world into various sections this can then be used for making all kinds of systems like a heat map pathfinding or defined valid on the area [Music] hello and welcome I'm your code monkey and this channel is all about helping you learn how to make your own games with NF tutorials made by a professional indie game developer so if you find the video helpful consider subscribing so here we are and this is what we want to make we have a nice scene here and as you can see our world is split into very squares each square is a grid position on our word map and when I click on a specific position you can see that it modified the underlying value on the grid map in that specific position this is a very simple grid map that you can extend to solve various problems for example you could use it to display where the mouse has been so here is a very simple example of the grid map being used in order to create a heat map alternatively you could use it to display where your player is dying or where he has killed enemies you could use it as a base for your pathfinding system to define which cells should be walkable and which should not or you could use it for example on a management game to define which areas you can build so as you can see there's a multitude of potential applications for this simple class for example in my own latest game battle royale tycoon I use grid maps for all sorts of things like for managing the path finding of each specific building to managing the town map for the ground towns as well as the environment heat map so as you can see there is a multitude of potential applications for this simple quest all right so this is our goal let's get to it okay so here we are in our scene all we have is a background texture and nothing else so let's begin by making our grid class over here on the scripts you see sharp script what's going on just great okay open it up now in here this will be a simple class so let's get rid of a monobehaviour and Sam let's make a constructor that receives a width and height let's also store these as variables now let's also create our underlying in terrain we're going to make a multi-dimensional array so we define it as int then brackets common brackets this is how we define a multi-dimensional array with two dimensions all right so now in here we create it so we do a new int array we pass in the width and the height all right so this is our very basic class we construct it with a width and height and we create the underlying array now let's set up a script in order to test it so back in the editor let's make a new c-sharp script let's call this our testing script let's make a game object to run it so a new game object call it testing and read the strip onto it okay okay so this script won't test our class so in here let's make a private void start and on start let's create a new grid with a certain width and height so let's create the grid object equals new grid and let's pass in width of 20 and a height of 10 okay that should do it now on the grid let's do it debug down low here on the constructor just to make sure that everything is worked so let's do a debug log of the width and then the height all right let's see any of their lives over here on the console say in 2010 okay great so we have our grid basic setup and the testing script is running now let's add some visuals to be able to see our int grid let's create some text objects that won't display the underlying value for each grid element so in here let's do a cycle to go through our entire array so let's do a simple form we start off at 0 and now in here since we have a multi-dimensional array we need to figure out the size of each dimension so we can get that by going into the grid array and comma get 1 and here you can see that we can give an int for the dimension so in this case let's cycle through the first mention and then inside we cycle through the second dimension so this is how you cycle through a multi-dimensional right alright so now it's in here that we want to display a certain element okay so here just make sure that our cycles were in curriculum with you a debug command on the text and then the one and just for testing let's reduce our grid to just four - all right so we got four in the width and two on the height let's see and you up on the console you can see that we are indeed cycling through our entire array so you go through 0 0 0 1 1 0 1 1 2 0 2 1 3 0 & 3 1 so we have 4 on the width and 2 on the height ok so far so good now in here let's phone a text object in order to visualize the underlining value for this grid element and for that I'm going to use a function from the utilities as long as you can download the utilities for free from in Tacoma Keep Calm so I'm going to be using code monkeytoes and in there in the utens class I have a create world text function here is the function in case you want to build it yourself instead of using the utilities as you can see just creates a game object positions it on a certain position creates a game object with a text match component sets all the text mesh values including the text so there it is very simple if you want to do it on your own but here let's use the utilities just to me make things easier for the text let's go into the grid array and grab on X Y so grab the underlying value and now in here we need to know where we're going to position our text object so let's figure out how we're going to define a position for our grid now in order to do that what we really need is to know how big each cell is so over here on the constructor let's receive a width then a height Emma let's also receive a point for the cell size let's store it up here and now with a certain cell size we can now calculate where each index lands on a worm position so let's make a function to convert an x and y into a warm position so here we make a profit going to return a vector3 oh it's called get world position now we're going to receive an int for the X and therefore t1 and now in here it's extremely simple we just return a new vector3 with our x and y x our cell signs and that's it very simple so now we can now use this function all the way up here to get the wrong position cus in the X and the one alright this should do it so we should now be able to see a text object being placed on every grid position so here I'm testing we created four two and let's also pass in the cell size and let's say 10 ax right so we should be able to see four times two so eight text objects let's see any of their days we can now visually see the underlying values of our grid you know text objects are correctly located with a cell size of 10 we can verify that by creating a new empty game object just to see there it is so that one is right there as you can see on 0 0 now we move around the side and this one is on 10 0 and the same up here is on 1010 awesome alright so now that we can see the underlying values let's also add a debug to see the size of each grid position so we're here where we're creating our text objects let's also do a debug drawn line so here we need a start and an end point so for start and let's use get the world position to the current X&Y for the animal let's get the world position of the X and the y pause one so we have our left side vertical line now it's also make the horizontal line on the bottom so instead of going to our pose 1 it's exposed 1 alright so just like this we should be able to see vertical line and a horizontal line then let's make it within color dot white then let's make it last for let's say a hundred seconds alright that should do it let's test alright here we are and we actually can't see anything and the reason for that is because we are using the bug drama so when you use that you need to go all the way up here in our to enable gizmos and there you go when you do that you can now enable and we can now see the edges of our quadrants so just like this you can see the quadrant starts in here it goes all the way up here this is one quadrant another one another one and so on now since we're only printing the on left-hand bottom that means over here on the top and on the right we don't have anything so let's set it right at the end so after we go through our array down here let's do a horizontal line so we're going to start off at 0 and at the height and we go towards the width and the height and then for the vertical line we start off at width and 0 and we go towards the width and height all right what says any of there it is our nice grade is now fully visible awesome however you can also see one slight issue which is that our text objects are right at the origin of each cell it would be much easier to read it if it was right in the middle so let's do that over here when we create our world test we're getting the world position and we can simply offset it by half of our cell size so we do pause a new vector3 let's put it cell size on the X cell size on the wine and then we multiply it by 0.5 so this won't shift it by half of the cell size let's see and there it is awesome so we can all visually see how our world map is split into various grid zones all right awesome so now that we can see the underlying values and see our grid let's make some functions you can modify it so first let's make a very simple function to set a single value so here let's make a public void let's call it set value we're going to receive an int for the X and int for the Y and then an int for the target value and now in here all we do is go into our grader right and set on position X Y to be our however here is also where we need to ask ourselves how should our class deal with invalid values so what should happen for example if we get a negative number there are very ways to solve that depending on what you're trying to go for we can either a thrown error or correct it to the closest value or just ignore it now throwing an error would potentially break the game so we should probably not do that and if we set the closest value then our grid map would behave very weirdly on the edges so in our case the best course of action is to simply ignore invalid values so in here before we set our value let's make sure that x and y are valid so we test if X is bigger than or equal to zero also make sure the Y is also bigger than or equal to zero and then let's make sure the X is out of the width and the Y is under our height without those that we have our valid votes and if we receive invalid X&Y we simply ignore it all right so far so good now in order to visually see setting the value we need to update our on text objects because in here we are simply creating them on the grid on the constructor and we're not obtaining it so if we use this this won't add update so let's see one with that let's make a second array just for debug purposes in order to store our debug text objects so here a private we're going to use a same multi-dimensional array but in this case of type text mesh we created just our like our underlying array and here when we are creating our debug test subjects let's set it for the X Y to be that all right so we now have a reference to our debug text objects again these are meant only for debug so when you go down here and we set the value let's also update our text object so we go into the X&Y and we set the text mesh text to be on the newly set bail all right that should do it over here on the constructor and let's test so let's call set value and let's try putting the value on the exit to Y of 1 let's write putting it to something like 56 all right so let's see and if there it is that one no longer has 0 go rather our new Lissa Valley awesome okay so now let's make a version of our function to set the value but instead of taking an x and y we're going to receive a world position so let's make a public void let's call it set value just the same except in here we'll receive effective 3 for the world position and then in for our value a now before we made a version to make the get the world position based on a certain X&Y and now we need the opposite we need a function to get the X&Y when given a certain vector 3 for the world position now in this function we need to return both the X and the y values however functions usually can only return a single them so we could modify all of our code to work with a struct that owns both the x and y values or we can simply add our parameters into this function so in here let's make this return point and instead let's have an out for need for our x and out int for our one this way we can return multiple values from a single function but again if you want it there are many approaches you could for example just make it return a vector 2 and and that would work the same but let's go with the out for now so in here in order to get our X all we're going to do is go into the method and the way for to in it we're going to for our world position dot x / our cell size so with the cell size of 10 the world position 5 won't be on grid 0 and the world position of 15 won't be ungraded 1 so that's how we calculated the X and the exact same thing for the Y and that's our calculation alright so we now have a function to convert our world position into a great position and we also have the previous one to convert grid into work awesome so now down here we can simply use that function so first we define our x and y then we call get XY we pass in the world position and we give an out for the x and an out for d1 and then we simply call set value with our converting XY and passing the Evo and that's it alright so now let's go into our testing class and in here let's test setting a value on our mouse click so let's do a cardioid update and in here let's test for any input in order to get the mouse button down let's test on the in left mouse button so in x0 now when we click let's set the value on the grip so in order to get the world position again we can use the code monkey details in order to get the mouse world position again here is the function in case you want to belt yourself we just go into the world camera and call screen to our point on the screen position so that's how we get the mouse world position and now in here we can now go into our grid so let's store a reference to the grid our grid we constructed on start and then in here we call grid set value passing the mouse world position and then let's pass in a valley all right so let's see if we can modify our grid by simply clicking on it all right so here we are now first of all let's click outside and yet there you go clicking outside those apps nothing since we decided to ignore invalid values however now if I go in here and I click yep there you go we updated our grid value so we can now easily modify our grid by simply clicking on the desired element all right awesome we have all of our code working perfectly now that we can set a value let's also make a function to get a valid so we're here on our grid we have our two set value functions let's make the equivalent in order to get a value so we're going to make a public going to return an INT call it get value and we receive an in for the X in for the Y and then here we validate the value the same way and if it's a valid Jolley we're returning from the grid array XY and if not then we have an invalid value so in here it's up to you we could for example return in minus 1 or in this case just return 0 how you dealing with infinite values is up to you let's make the same thing for the world position version all right we have our two very nice functions now let's test them so in here let's read the value on the right mouse button so in here just doing a debug log getting the value on the mauser opposition alright let's test ok here we are and I right-click outside and it always print 0 there this you know I right click in here says 0 left click and I've set it to 56 right click and there you go it is now correctly reading so that one read 0 10 reads 56 awesome so you can now set and get values from our grid all right now something else very useful is to have a variable origin up until now our grid does all the calculations assuming the origin is on 0 0 but sometimes you want your grid to start at a different point for example in parallel tycoon I have a grid created for each building and each building is located not in a different position so in here on let's go into our constructor right let's receive all of this and then let's also receive a vector3 for the origin position all right we have our origin and now down here whenever we are doing our calculations in order to get the wrong position or get the X Y when converting a great position into our position we do this and then we simply add our origin and the reverse getting the world from the XY we simply have our world position then we subtract our origin position and then we get the X in the Y all right that should do it let's test it out so here on testing let's set our origin instead of being on zero zero let's put it to the right so let's say on 20 0 km let's see so here we are and we can pause the game and look at it let's create an empty game object just to see where it is located and there you go zero zero is in here and over here on the right as you can see the origin is on 20 0 and let's see if the clicking still works so click out here nothing happens click over here and yep nothing is set and when I click in there there you go except that one that one that one and read also works awesome all right so that's pretty much our basic grade class done we TransAm make as many grades as we want with whatever size we want so let's try and make me bread with five let's put it under then let's put another one with 20 all right so here we have a whole bunch of different grids each of them has a different cell size different with different height and they all work the same underneath so you can see how this class this code is extremely adaptable to whatever needs you have so again using this Bayes there's a ton of stuff that you can do with it now in here I will quickly show several potential uses for this grid map I'm going to make a simple heat map to show where the mouse has been I plan to do a completely detailed video on a heat map but right now I just want to show what can be done using this as a base all right so here we are with a nice simple heat map this was made to show where the mass has been so whenever I pass over the mouse there you go as you can see the Mazda leaves a trail wherever it goes you can see a heat map with the color so if I leave it there it goes from red to yellow to green and it shows how long the mouse has been on a certain position so there you go this is a very simple use case of the underlying grid so it's really doing is increasing the value on the underlying grid position under the mouse and converting that value into a nice cone in order to make that work I just added a few things over here to the grid like for example this event this gets fired whenever the grid value changed so down here when you have the set value we fire off this event and then over here on the testing class I created the heatmap visual as you can see it receives a grid then it updates when the grid value changes and the update simply creates the mesh if you'd like to know how a mesh is created through code check out the recent video I did on creating a dynamic mesh so here then just get see great value and sets the UV in order to change color of that quadrant any or Lissie texture that I'm using as you can see just has one pixel in black then it goes red yellow green again I plan on doing a complete video detailing the creation of a heat map but right now I just want to show one possible use case for this very simple underlying grid class I'm also planning another video on how to extend this class use generics so you can expand it even further so stay tuned for all of that as always you can download the project files in utilities from unity code monkey comm if you liked the video subscribe the channel for more ent tutorials post any questions you have in the comments and I'll do my best to answer them alright see you next time [Music]
Info
Channel: Code Monkey
Views: 259,484
Rating: undefined out of 5
Keywords: unity grid system, unity grid, unity grid map, unity heatmap, unity grid placement system, unity map system, unity grid placement, unity heat map, unity grid world, unity heatmap tutorial, unity map, unity grid building system, unity quadrant system, unity quadrant, unity world map, code monkey, brackeys, unity tutorial, unity game tutorial, unity tutorial for beginners, unity 2d tutorial, unity 3d, unity 3d tutorials, unity tutorial 2d, unity2d, unity3d, unity
Id: waEsGu--9P8
Channel Id: undefined
Length: 23min 43sec (1423 seconds)
Published: Fri Oct 04 2019
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.