Welcome back everybody today we’re getting started on creating a 3d world so a 3d mesh generated world completely procedurally via code um so in the first episode today i’m just going to walk through some of the 3d mesh generation basics what makes up a mesh blah blah blah The boring theory stuff and then we’ll also get to generating a face or a whole cube depending on how we go um but yeah so let’s get straight into it so our world is going to be made up of these cubes um obviously a cube has eight corners uh visibly So to generate it we obviously have to theoretically put eight corners and say hey draw our faces between these corners right well kind of um so we’re gonna generate each face one by one uh face has four corners or we call them vertices in mesh generation Um or some people may call them vertices in general but that’s what we call them in computer language um every quad or face every four-sided shape that’s what quad is a four-cornered shape has is made up of two triangles in a mesh so two triangles make up a square obviously um and technically These would now have six corners if that made sense um if we’re using a low poly shaded style however since the both these faces are going to use the same lighting then we can obviously share their vertices that’s fine um if they were gonna have different lighting then which We’ll get into as well then you would have to have six separate vertices um for each triangle uh and all that so here’s what we know that three vertices for each triangle gives us six vertices on a square but lighting normals this is what i was mentioning before so Normals determine which way a face is facing um and how and therefore how it is affected by lighting because this phase here should not be affected as much of lighting if there’s a light on this side where my mouse is here um it shouldn’t be affected as much as The face on the top and that’s what normal determine helps determine that um but how can we tell a triangle which way to face quite simple we declare our vertices in a clockwise order and that way we can determine that our faces you know face the right way so to do this in A in code right we’re going to determine a face by creating four vertices starting at zero obviously in computers um so we go zero one two three four that’s how we’re going to determine it um every vertex obviously has its position so we have to declare a vertex give it Its position and say hey put a vertex here and then we’re gonna for each triangle we’re gonna say all right this triangle is made up of the zero second and the first vertex and then the next triangle is going to be made up of the second third and the first vertex why am I putting in that order and not just one two three again declare it in clockwise order start from two three one that way the normals face the right away if i was to do one three two then my face would be facing the other way and that Is a problem because then we just have an invisible face so let’s get into coding this okay everyone so inside unity i’m just going to go ahead and create a new material to begin and this material is just me called matte and i’m gonna set the smoothness to zero It’s just gonna be a default material that we can use on our mesh i’m gonna create a new game object and i’m gonna call this cube and i’m gonna reset its position and now i’m gonna create a new c sharp script and this is going to generate each cube So i’m just going to call this cube and then let’s double click the script open it up okay so we don’t need any of this and we don’t need this um for the time being for this episode this first initiative i’m just going to generate a cube Um and then from there we’ll we will move on to generating um more cubes setting textures and whatnot as well we might do textures in this episode depending on how we go as well but yeah so let’s see um first thing i’m going to do is create a public Um in fact let’s just start with the pub private void start right and this is going to call a void generate face um we’re going to have a different function to generate each face so we’ll worry about that later for now i’m just going to call generate face Um that’s fine we also need a public mesh mesh um this script to behave properly it requires a couple components so the way we declare a component like that is to simply inside square brackets at the start say require components type off and the type of is mesh filter And the mesh filter is just going to show the mesh so it’s going to hold the mesh and it’s going to be the mesh data and then we also need a mesh renderer to actually render that mesh nice um and then for our mesh to work we need a list Of vertices well an array of vertices in an array of triangles however since our vertices and triangles the number is dynamic since we’re not going to always generate every single face in the future it could be since we don’t want to generate faces in between blocks There’s no point um it’s just a waste of performance so we’re going to use a list to make it more malleable so i’m going to declare using system.collections.collections dot generic there we go and now i can declare a list by saying public list vector3 and this vector3 list is going to hold Our vertices positions and it’s going to equal new lists of type vector3 blah blah blah that’s easy we go and then a public list of type ins and the ins are going to be our triangles equals new list of type and perfect cool that’s literally all it is um we will also have Uvs and stuff which we’ll set uh should i set that now probably not worth setting it now but i will include it just anyway um so i’m gonna have a public list of oh not that one public list public list there we go and uvs are stored as vector twos So here we go call it uvs it’s gonna equal new list or type vector2 cool um now at the start we want to say mesh equals new mesh just so we can create a new mesh um and then after we generate all our faces so here we initialize the mesh and then we Create the mesh data from all these faces and then we set the mesh data now to set the mesh data quite simple all we have to do is just say mesh dot vertices equals vertices mesh dot triangles equals triangles and then mesh dot uvs uh well it will be mesh.set uvs And we want to set it to the first channel and then the uv is just uvs um now here’s the issue measured vertices is actually an array of vector3s ours is a list so how do we convert a list to an array quite simply we can just press do to array and that Will do it for us anyway so nice and easy like that um and then same for this this should be uv’s dot to array i believe but it should take in a list as well i’ll just pass in dot 2 array just to make it a little bit more consistent Um cool that should be it’s i believe cool so i’m going to rename generate face to generate um front face i’ll do in fact i will just do front underscore generate face um just to make it easier when it’s auto completing for us saves us from having to write as much um Cool so that’s gonna do that i might create another void here to say draw cube um it’s just going to be called draw cube and then i’m going to move this line to draw cube so that i can just call draw cube instead there we go now generate front face is Has a so as we mentioned in the at the start well as i mentioned at the start of the video how our um mesh is constructed is by vertices and triangles so let’s create the vertices the way we’re going to create our vertices is just we can say vertices.add because it’s a List so we can just add the list of vertices that we’re going to have what we also want to do is take in a position um so our draw cube is going to take in a vector3 position all our faces uh should not take in a position actually because that’s going to Be a lot of effort so i’m thinking rather than even doing this we might just be able to create a position up here yes we can do public vector3 position yeah yeah we can do that so public vector3 position um and then here i can just do that position and obviously our first Vertices is going to be exactly where our cube is positioned so that will make sense in a bit um our next vertex is going to be positioned at does that make sense face front face uh this will be position plus vector three dot forward and then this will be position plus vector three Dot forwards plus vector three dots um up so this is in other words if we’re looking at it from the front of the cube um this is the bottom left corner then this is the top left corner this is going to be the top right corner now so i’m going to do Plus vector 3. forward plus a vector plus vector forward plus vector 3 dots um i’ll have to do one and then duplicate it again and this one’s gonna do plus vector3 dot forward plus and the reason i have to do dot forward for all of them is because this is going to be One unit in front of our mesh so that the face at the back of the cube is at zero zero if that makes sense um well as we start rendering them you’ll start making a little bit more sense to you guys um regardless let’s so this one’s going to add Vector 3.4 plus vector 3. right cool that should be all our vertices declared so i’m just going to say declare vertices we also need a integer to keep track of the last vertex and the reason that’s important is so that our triangles when they reference our vertices It can keep track of which vertices belong where um because they have to reference them by index or the triangles so what i’m going to do is just create a private and last vertex um here i’m going to say last vertex equals vertices dot count so it equals the Latest one and then here i can just say triangles dot adds and for each one i’m going to first do last vertex plus and then whichever one i want to do so the the way we declare triangles is in three in blocks of three obviously each block well each line Declares it to a certain vertices so for example if i say triangles dot add right and i add zero well plus a zero that’s going to reference this one this line if i do plus one then this one then two then three so in other words i can just do plus I’m gonna declare them like this add little commas just to keep track of it a little bit easier for us and you remember from our slideshow if you want to flick back to that um that’s that’s how we these are the positions and that’s just the Number of that vertice um so now when i do plus a zero obviously i can just do last vertex instead so we’re starting at the bottom left corner and we have to declare them in clockwise order of course so then we’re going to go to the Top left corner so i can just say plus one then we’re going to go to of course the bottom right is it uh 3.4.1 no that one yes so plus two yes and this is actually our first triangle and remember each square is made up of two triangles so we Need the second one so i’m going to copy that place that here and this is our second triangle and our second triangle is going to start at the first index again this time i think it’s going to go to number three and then number one or is it two uh started Forward then it will go to right instead so three and then one yes that is correct awesome um and then our uvs will set later when we actually have textures because that’s getting a little bit more into things so with that all done i believe that might actually work already not 100 Sure but so we have this cube game object i’m going to drag and drop our cube script onto it first and then drag and drop our material script um with that done if i press play we are not setting the mesh that’s why okay so that’s another thing i have To do after we um set the mesh data we also have to actually set the mesh itself so we can do get components mesh filter dot mesh equals mesh and that will actually apply the mesh to the mesh filter so that the mesh renderer can show it I think you go we have something generating and it is slightly off it looks like so there is definitely something in the wrong position here um it looks like rather than doing the center if i do pivot so firstly one of the triangles is facing the wrong way It looks like the first triangle is facing the wrong way and it looks like our third vertex is in the wrong position uh because i’m doing plus vector 3.1 uh yes this should be plus vector3 dot forward um plus up plus right i think it should be plus vector3 dots Right um and then to make our last to make that initial face face the other way we’ll probably have to switch out these like that and render the face backwards something along those lines i think okay so interestingly now it’s rendering backwards so if i make this The other way again if i don’t flip them over then what happens still facing backwards like this two one and then zero there we go perfect so that is a better we just have to do the same for every face so it’s a little bit more complicated Um but once you get the hang of it it makes a little bit more sense so the one other thing that we also have to do is recalculate the light ink so that’s what i’m going to do now recalculate light ink and the way we do that is Luckily we don’t have to do much complicated stuff for that we can just say mesh dot recalculate normals and that will do it for us automatically which is nice and handy um now of course we have to duplicate the front face which is a little bit of a hassle but if um What i’m going to do is just select all of it bit ctrl c and then right here ctrl v and then i’m going to name this back underscore generate face and for backdoor and on general face it’s as easy as just getting rid of vector3 dot forward for each of these vertices Um same with this one same with this one and then we just have to make sure that we flip over the triangles so that they render backwards essentially so i can make this one go up there and then this one go there and then two at the start and then three In the middle there we go and that should give us two faces of our cube um it gave us one face of our cube uh right because we’re not actually calling that function my bad my bad um we also want to say back underscore generate face and then that should work And that’s why we have to carry the last vertex because this last vertex this cube would not generate if we didn’t carry the last vertex um which is why we have to do it that way and there is a better way to do it Do this so that we don’t have to have a separate function for every face i did try that issue is it messes with the uvs the faces become odd rotated and stuff and i’m sure there’s a way to make it like better but apart from that let’s create the Other faces as well now so each time we do a block of a face so if i do right face now um this one’s going to be a little bit more tricky because obviously i’m going to also do right generic case because now we’re dealing with two different axes so our right face Is going to be facing obviously the right so the pause is initially going to be vector3 dot right then it’s going to go to pause plus vector3.writes plus vector3 uh is it vector through the up plus yes vector three dots up um is that correct the front goes from bottom up And then yeah okay and then this one will be um plus vector 3.1 and then this one is going to be plus vector3 dot right plus a vector 3 dot forwards something like that let me render this and see what happens did that work um yes it did Cool so that’s our right face done as well and you’ll see how all these triangles point the same way this diagonal line that is important uh for the back face it doesn’t we could make it point the same way as well if we really wanted to personally it doesn’t matter too much For them to flip um but you know what maybe i should should i uh you know what i probably should gonna do it might as well do it right so to make that render properly on the back face what we’d have to do is start it at rather than pause We want to start it at pause plus vector3 dot right and then we would go to positive vector3.up plus vector3.right then go to positive vector 3. up and then go to pause yes and then we will have to probably flip these vertices around as well these triangles so like this um Like this so it would be two one nothing and then nothing three two yes so the right face is facing the wrong way so to make our life a little bit easier uh rather than having to rewrite the right face it’s a blessing of the size this is actually going to now be Our left face what i can simply do is get rid of vector3.write get rid of vector three dot right there get rid of vector three dot right there and this one will just be not vector three dot one it will be vector three dot forwards plus a vector three dot Up um and then i’ll have to flip the triangles around as well there we go and now that is our left face cool so if i generate this we should get a left face we won’t get the right face instead um indeed we do and they’re all facing The right way cool now we just have to do our right face properly this time so let me minimize that copy that whole thing there we go now let’s call this right let me control c this which will be there and call this right give you a couple Yeah um cool so our right face is going to start at uh let’s have a look where is it going to start it’s going to start at vector3 dot right plus vector3 dot forward so yes plus a vector3 delta right plus a vector3 dot forward then it will go to vector3 dot One then go to vector three dot right plus vector three dot up and then go to vector three dot right um i think something like that yes there we go we have four sides of our cube done and the correct rotations of vertices which is good um and now we Just have to do the top and bottom so i hope you guys are being able to follow along so far mesh generation is not meant to be easy so if it is easy for you at the moment then you’re doing something wrong um so we’ve done that okay so this is Going to be our top face pop should be easier he says so top so the rotations right top and bottom don’t matter too much because they’re not going to be in sync um that said the rotations for any of them don’t really matter realistically as long as they’re facing As long as the diagonals are going in the right direction um otherwise your textures will be rotated in odd ways so i’m also going to call top dot generate face here um for this one simply gonna say plus vector three this one will start at pause plus vector three dot up Dot up yes uh vector three dot r um is that right no we will start this at vector3 dot up plus vector3 dot right yes and then we will go to vector three dot one and then we will go to vector three dot forwards dot up yes um And then we can go to vector three dot up just as is and that should give us our top face indeed it does cool slowly getting there now we just have to do the bottom phase and then that ladies and gentlemen is our cube complete so let me copy this whole Function as well just like that call this bottom nice um this one i’ll show you gotta call bottom face here um and the reason these are all separate as well if you don’t understand why i’ve done that is so that i can just say if we need to render the front phrase of Under the front face if we need to render back and render back so on um so we’re not wasting time rendering faces which aren’t even going to be visible and it also optimizes the mesh a lot otherwise because a mesh can only have a certain max number of vertices for those who Didn’t know it’s a very large number but um that said that number especially when dealing with a lot of vertices and a lot of cubes fills up quite quickly a lot more quickly than you could than you would imagine um that’s it let’s do the bottom face really quick so for this one It will start at a vector3 dot up and then uh yes so we’ll start at vector3.up no vector sorry it will start at pause then go to vect pause plus vector3 dot forward then pause dot vector3 dot forward plus right and then pause plus right as is and that should give us Our bottom face and it does perfect so we have a fully generating cube um nice and simple there we go we have a coupe perfect and this will be fully customizable with its material and everything as well yeah cool that worked nice oh my god that was a hassle and a half But we have done it shall we add textures no no let’s not add textures we’ll do that in the next episode yes in between episodes i already have my textures here ready uh i’m just using the same kidney assets that we did for the 2d sandbox series They’re all ready for me um if you guys wanna in between episodes go get some of your own textures or there will be a link to this um where you can get these textures from in the description um but yeah so what we’re gonna do in the next episode is create some uvs Well we have the uvs created we’re actually going to utilize them and have some textures generating on our cube so we have the grass textures and everything rendering uh make it look nice and pretty but yeah that’s it for today i will catch you guys in the next one take care and peace Video Information
This video, titled ‘Procedural voxel terrain generation in Unity #1 – Creating a cube!’, was uploaded by ErenCode on 2021-08-01 03:20:03. It has garnered 13170 views and 175 likes. The duration of the video is 00:27:48 or 1668 seconds.
In this tutorial series we learn how to create 3D procedurally generated terrain to create 3D worlds like Minecraft in Unity using voxels and Perlin noise. Voxel worlds are used with Perlin noise to create all kinds of terrain generation from marching cubes, to blocky terrain. We learn how to generate 3d models and meshes to create Minecraft, and No Man’s Sky – like terrain from start to finish using nothing but code in Unity!
In this first episode we write a script to generate our first cube!
All code licensed under MIT license: https://docs.google.com/document/d/1cz3rRhMUg2rHzT2XOfNNvUI5eWYd16NeodbZlccKk3E/edit?usp=sharing
✅ Join the Discord : https://discord.gg/K4fQ6s82Q4
🔴 Subscribe! : https://www.youtube.com/craazypelican
Resources: https://docs.unity3d.com/Manual/GeneratingMeshGeometryProcedurally.html
https://docs.unity3d.com/Manual/Example-CreatingaBillboardPlane.html