In the previous video we have implemented our blog helper script and now finally we are able to fill in our world script and to generate our visualizations for our voxel world so let’s get started first of all we will open up our world placeholder script that we have created a while ago Great first thing that i will want to do is delete start and update this will be a model behavior script and we will need to have couple of fields here i’ll paste them first we will have a public int that will be map size in chunks so to have a way to Measure our map we can measure it in chunks because we may not be able to render with our system half of our chunk we need to create a whole chunk that’s why we have a map size in chunks we are going to simply multiply it by the chunk Size that we have below public in chunk size and chunk height this will be 16 and 100. next we are going to have a public int water threshold this will allow us to create a water surface at some specific height of our chunk next we have a public float noise scale This will be 0.03 f so this will be a float value and this will be useful when we want to generate our noise using the purlin noise from the math f library of unity we are going to create a more sophisticated way to generate noise value and to generate our terrain In the next section of this series for now we are going to use this to generate a example terrain and we are going to have public game object chunk prefab reference the prefab that we have created in the previous video or couple of videos ago and we will have two dictionaries those Will be the dictionary of the vector3 and the chunk data and vector3 in chunk renderer the second dictionary will allow us to simply remove the chunks from our map and the first one will allow us to store the data about chunks that we want to generate on our Map this will be much more useful in the second section of the series for now we are going to only use those to store the data to render our chunk and remove them if we want to regenerate our map now to generate our world first we will need to generate our chunk data Now we are generating it in this fashion because later on when we in third section generate our code in a way that is multi-threaded it will be much more easy to generate the data first and then only to render it when we have all the data created So we are going to first of all take care of generating our data so i’ll create a new method here and this method will be called private void generate voxels this will take in the chunk data data this will be a new data that we create And we are going to look for each x and z coordinate and we are going to clip from zero to chunk size and from zero to chunk size so we are looping through the coordinates in the chunk local space so it doesn’t matter where the chunk is placed in the world We are setting the chunk the voxels of our chuck in the local space of our chunks from zero to the chunk size next we are going to simply use the mathf.pearly noise to generate our noise value that we will use to set the level of our ground now we Are going to talk more about the noise and generating our different terrain using this noise function in the second section for now we are going to simply pass to it our world position of the chunk data plus the x value from the for loop and the z value for the for Loop for the second parameter as our math f dot pearly noise takes x and y value and generate our float value noise value between 0 and 1 and the noise is continuous so that we have this continuous wave like shape for our terrain next we are going to multiply this by The noise scale that we have provided at the top just to see how our generator generates our voxel world we’re going to do the same for the z value for the second parameter of our math f dot purlin noise method next we will need to of course Round it to int value and to do it we know that noise value is between zero and one we multiply it by the chunk height and we round it to an in value using mathf.run to int to get the integer value so on this level there will be the grass style Or dirt style generated above there will be water or air and below there will be dirt next we look for each y value from 0 to the chunk height and since we are only considering now the chunks that are above the ground so those chunks contain Some ground and the ground level and the air above the ground and for those chunks we are going to look for each y value and we will need to create a block type this will be basic block types of dirt dirt will be always spawned if our Y value is below the terrain height generated from the pearly noise so this will be the ground position integer value if y is greater than the ground level we are going to check the water threshold if we are below the water threshold we want to generate a water body Below this y value else we are going to generate the air voxels those will not generate any meshes and there water will be only generated when it meets the air voxels we will see the results soon else if we are on the ground level we want to generate the voxel type Equals block type dot grass dirt block type we have generated in one of the first videos of the series so we are going to generate the grass dirt voxel and if none of those are met we are going to use the default block type.dirt and all we need to do is call The chunk our static class to work with our data our chunk data we are going to call setblock we are going to pass the data the position x y and z taken from this loop so this is in the chunk coordinates and we are going to pass the voxel type To set the block type in our blocks array in our data so if we go to our chunk data go to the definition we are going to set this inside our block and we are going to set the appropriate index with the type that we have generated Great now to use this we will need to have a new method a one that will be called by us using a button so let me paste it above and this will be called public void generate world so to generate our world we first need to take care of what was previously generated That is stored in the chunk data dictionary in chunk dictionary so we want to clear the chunk data dictionary we want to destroy all the chunks to do this we are going to look for each chunk render chunk in the chunk dictionary keys so this is the key so our those are the Chunk renders and we are going to destroy the chunk.game object to destroy all the chunks that are present in our unity project next we are going to clear this dictionary and here is the mid of our and here will be the main code of our method We are going to look for each x and actually this should be z so let me rename it to z we’re going to look for hx and z value in the map size up until the map size in chunks value and we are going to generate the Data chunk data data equals new chunk data we are going to pass the chunk size chunk height the world reference will be this world and the position will be vector3 int x so this is the value of zero to chunk map size in chunks this was six by default times the Chunk size so this will be 0 16 32 and so on because our chunk size is 16 the same will be with the z value and y value will be 0 since we are generating our chunks above the ground next we are going to call our method generate voxels for this data to Generate the data and we are going to add it to our dictionary let me fix the issue in the editor because i have forgotten one parenthesis in this for each loop we are going to look for each data in the chunk datadictionary.values and we are going to generate our mesh Data by calling the chunk get chunk mesh data method if you recall we didn’t finish implementing this method right click and select go to definition and here we have this command fill later so i’m going to fill this we are going to use the loop through the block method that we have implemented And this is the first method of this chunk class and this will simply look for each block in our chunk data so we pass the chunk data x y and z coordinate and we are going to receive those from the from the for loop that is inside our loop through the blocks And we are going to then take it as and set our mesh data to be equal to our block helper dot get mesh data again this is the method that we have implemented in the previous video and we are going to pass all the data so the check data X y and z mesh data and chunk data dot blocks and we are going to select the specific block using the get index from position method and we are going to pass to it another set of data and since we are passing to it the current mesh data We are updating this mesh data and returning it as the new mesh data so at the end we are going to receive all the voxel mesh data for our single chunk and we are going to return it so that we can generate it now unfortunately there is one more Method that we need to fill in at the bot at the top of this class we had this git block from chunk coordinates method and if this wasn’t in range of our current chunk we have thrown an exception because we had no way to access the neighbor chunks In our world but now we have our world script that has the dictionary of all the chunks so we can ask the world about the correct chunk that we have we should access to get this block and this is useful when we want to generate our Blocks our mesh data for the blocks at the edges of our chunk because maybe there is another chunk and it has air or ground on this block that is the neighbor of our current chunk block and we need to know what is the type of the block that is neighboring This current block in the second chunk in the neighboring chunk so to do this we are going to delete this throw statement since this will break our code and then we will need to add here some code so i’m going to paste here them a callback to our chunk data So this is the data that we have passed and it has the reference to the world that it is using and we are going to generate a new method get blocked from chunk coordinates inside our world and we are going to pass basically the same data to have passed here so chunk data And instead of the x y and z which are in the local chunk space we are going to add to them the chunk dot worldposition.x y and z so that we have the block coordinates in the world space instead and we can select our get block from chunk coordinates method and I can right click click actions and i can select generate method inside our world and this will be now generated but we will need to fill it in ctrl s to save your script and i’m going to right click and go to the definition of this newly created method Now here we will need to access the correct chunk for our block to be able to get the type of it now let me paste the code here we’re going to call vector3 into that position equals chunk dot check position from the block chords again This is not what we have in our chunk so we are going to create it but we are going to pass here x y and z instead of this v1 v2 v3 and now we are going to right click on this method and quick actions and generate this method this will be Getting the chunk position from the block coordinates so right click and go to the definition all we need to do here is to take our coordinates x y and z of the specific block in world coordinates and we are going to create a new vector3 int called position Equals new vector3 int and we are going to floor to end the value of x divided by the floored float world chunk size so if we know that the chunk size is 16 and the x is 33 then we divide it by the 16 and we get the two point Something so we are going to flow it to end and we are going to get two so we are going to multiply 2 by the world size chunk size so it is 16 we are going to get the position 32 and 32 will be a valid position of Our chunk so this is how we are going to get the correct positions of our chunk we are going to return it and if we go back to our world script so now we need to access the chunk data for this chunk to do this we are going to access Our chunk data dictionary dot try to get value and this method allows us to pass the key and pass the chunk data value as the with the out keyword so if this finds this value it will output it to this reference value here to the chunk data Now if this dictionary doesn’t get this value doesn’t find this key it will return a null and if this is null we are going to return the block type dot nothing so we do not render anything on this position so we do not render the phase of our current block Else we are going to get the position of our block from this chunk that we have found so we are going to use chunk.getblock in chunk coordinates and we are going to pass this container chunk as the chunk of chunk data to find this block in And we are going to pass the new vector 3 into x y and z those are the positions in the chunk local space of this block and we are going to pass here the x y and z value world position so this will give us the correct position of our block And all we need to do is to return our chunk get block from chunk coordinates again we are going to pass the chunk data as the input and the position of our block to get the correct block type from this chunk or if this chunk doesn’t exist we are Going to receive the block type that nothing okay this was a lot but we are almost done what we need to do is select file and save all just to make sure that we have saved all the scripts and we are going to go back to unity now If you have any errors here you may want to download the full project from the google drive or check the scripts against the github link both links will be in the description of this video what we will need to do now is right click oh i have this cube i’m going to Delete it right click and create an empty object in the heart key and i’m going to call it world and i’m going to reset the transform of it reset and i’m going to drag here our world we have the map size in chunk 6 chunk size 16 height 100 water Thresholds let’s set it to 39 and we’re going to have the noise scale equals 0.03 now we need only to add the chunk prefab which we have saved in the assets in my case i’m going to drag it as the chunk prefab next we are going to right click in the hierarchy Ui and create a simple button now i will select the canvas first and select the canvas scalar ui scale mode and scale with screen size next i am going to select the button click the anchor point hold shift and alt to anchor it in the bottom left corner and i’m going to Change the text to be regenerate okay and all i need to do is select our button add on click listener and we are going to add our world as the object and select our world and select generate world as the method that will be called now let’s save our scene and if everything Went well we can simply press play and click our gen regenerate and we will have our world generated and it is all made out of voxels if you select one of those pieces you will be able to see that this is a single chunk if you don’t want to see this ui Select the layers and uncheck the eye icon for the ui and you can see that this is just a set of faces it’s a single mesh if we rotate around we can see that none of the faces around this were generated to save our computational power we have our water generated on the Surface and this is transparent this is using a different material the material one water material so we can see through it and it creates an illusion of our water what we have achieved in this series is a voxel engine that can generate us the voxel world now if we want to Modify our world let’s select our world and change the noise value to be something like 0.09 and let’s click regenerate and you can see that it takes quite a while to generate our world okay and again let’s try it again with this some 0.01 value Now just to show you how much you are saving by not rendering all the faces let’s select one of the chunks here and you can see that those are two meshes this is one is the land the ground and the second one is the sub mesh of the water and if we Select in the inspector the chunk render script at the bottom if we select two gizmos we should be able to see that this is actually our chunk so this is our chunk and we can see that it goes pretty high and if we were to generate this part Especially this part below our ground with faces it will be much more faces that we currently have rendering only what we need okay thank you very much for watching this series in the next one we are going to work on polishing the way we generate our world So hopefully it will look much better than we what we currently have again if you have enjoyed this tutorial leave a like leave a comment subscribe and i would really appreciate your support through patreon or by purchasing my udemy courses then links will be in the description of this video Thanks to all your support i will be able to create more free youtube unity tutorials thanks a lot for watching take care Video Information
This video, titled ‘Create MINECRAFT in Unity – S1 – P11 Rendering the terrain’, was uploaded by Sunny Valley Studio on 2021-05-25 12:54:10. It has garnered 11282 views and 246 likes. The duration of the video is 00:19:51 or 1191 seconds.
In the Section 1 of this procedural voxel world generation Unity 2020 tutorial we will start by creating a codebase to generate the terrain using voxels. We will need to write a bit of code so instead of retyping the code copy it from github or use the end project from google drive (links below).
Section 1 – Voxel Terrain Engine https://youtube.com/playlist?list=PLcRSafycjWFdYej0h_9sMD6rEUCpa7hDH
Section 2 – https://www.youtube.com/playlist?list=PLcRSafycjWFesScBq3JgHMNd9Tidvk9hE
Section 3 – https://www.youtube.com/playlist?list=PLcRSafycjWFceHTT-m5wU51oVlJySCJbr
Learn more from about Unity Game Dev in my video courses at: https://courses.sunnyvalleystudio.com/
Starter project files: https://github.com/SunnyValleyStudio/Unity-2020-Voxel-World-Tutorial-Section-1-starter-project
Code files for everyone: https://www.subscribepage.com/voxel_world_tutorial_section_2
Project / code files for patreons: https://www.patreon.com/posts/voxel-world-end-53323870?utm_medium=clipboard_copy&utm_source=copy_to_clipboard&utm_campaign=postshare
Project / code files for YT members: Link in members only community post: https://www.youtube.com/c/SunnyValleyStudio/community
You can support me through Patreon: https://www.patreon.com/sunnyvalleystudio
I have used this tutorial by AlexStv as a reference to create this series: https://forum.unity.com/threads/tutorial-procedural-meshes-and-voxel-terrain-c.198651/
Join the discord if you have any questions! https://discord.gg/RQEtYHz