top of page

Fast Chunks - 2 - InterChunk

Dernière mise à jour : 28 juin 2018



Now that we created our chunk, we want to make more of them.


Let's make more chunks!

In the project folder, we need a new script called "World". It will create our chunks and manage them and the whole world.

That's what you should have. The Block_Cube constructor, a Chunk script and the World script


- Now open your World script and let's add some variables :

- Here, we have the terrain material, it won't be in the chunk script anymore.

- We need, for now, a worldSize value. This is how many chunks you will create in each direction on the axis.

- We will also set the chunkSize here now.

- Finally, we need a Dictionnary to store every chunk we generate.

Here, we will store the chunks with a Vector3 value. So when we need a Chunk at a certain position, we can get the one we need in the Dictionnary by looking at the position stored in it.


So, we can go to our Chunk script in the project folder and change a few things :


Remove the chunkSize variable, it is now in the World script.

We need the chunk material and the variable where the new chunk object will be created. This script won't be attached to an object anymore but it will generate an object chunk at a position and store it's values.


- So, we will remove RequireComponent and make it a class with does not depends on MonoBehaviour anymore. It will be generated by the World script :

In order to create a new Chunk class, we need a constructor :

We make the "Chunk" constructor with it's position and the terrain material which will be given by the world script.

- First, the Chunk will create a physical object of itself. That's where we will generate it's shape with the values we get.

- Then we store in this instance the position and the material we gave.

- Finally, we replace and call the Start method now called "MakeChunk".


Go to the GenerateVirtualMap method and remove the last line. We won't generate the blocks right now. Because they have to check for their neighbour. The world will generate them when the chunks will be created in the dictionnary.

We will need to check a block in the neighbour chunk but if we create the chunk before the neighbour is created, it will lead to errors. We want to generate the neighbour chunk before.

Also, set the GenerateBlocksMap method to public.

Finally, go to the GeneratePhysicalChunk method :

We want to add the MeshFilter and the MeshRenderer to the chunk object which will be generated.

Remember that the script is not attached to the chunk object but the chunk object is attached to the script.


PHEW! That was a big part to change! You can take a break now.


_________________________________


Now we can generate!


So.. let's continue by creating those chunks in the world from the World script.


Go back to the World script.

We will add a new method called "CreateChunk". It will be called when we want to create a chunk and will take care of setting up every new one:

When we call this method, we give the position of the new chunk.

- First, we prepare a new chunk class, it will be our new chunk. We give to the constructor a position and the terrain material.

- Then, we add it to the list of chunks with it's position and which chunk we add (Here, the new one on the line above).


Go to the Start method : In the Start method, we can add new lines. We want to create our chunks in each direction with the "worldSize" variable :

Again, we use our 3 loops to make the chunks on the x,y,z axis.

But here, we have some calculations to do :

We start at position 0 and we create a chunk. Then every chunkSize we add a new one. Meaning that we want to create chunks side by side and read the size of our chunks to find how much units we have to go to in order to make the new one. If we had a chunk with a size of 10x10, we will create chunks every 10 units.

Also, for the condition of the loop, we could say "Until we reach the worldSize" but we add our chunkSize every time to it. So we multiply the worldSize with the chunkSize.


Everything will be translated to : "From 0, until we reach the full size of the world (chunk + chunk + chunk + chunk...) which is worldSize * number of chunks, we make a chunk every chunkSize unit.


To create the chunk, we call the method we made, "CreateChunk". And we give the position of the loops which is the position of the new chunk.


After we made our chunks, we use "foreach" and "KeyValuePair" to look inside the Dictionnary and for every chunk we generated, we make them physically by calling their GenerateBlockMap method.


Now you can test your game in Unity :

Our chunks now exist in the world.

But there is something we still have to fix :

We managed to fix the inter-block generation, avoiding the chunk to draw quads between blocks. But we have to do the same between chunks now.


Let me explain :

Chunks are independent objects. Each one of them contains it's own blocks. Block positions are the same for each chunk.

For example, the block at chunkMap[2,10,7] exists in every block (If chunkSize is big enough).

So, we have to ask our neighbour chunk if there is a block at the position we want to look at.

So, let's do some maths!


So.. what if you want to know in which chunk the block number 6 is stored. (Remember that blocks are not independent, this is a whole chunk with it's own position in the world).


We have chunks made of 4x4 blocks.

Divide 6 by 4 and you have 1.5.

Now bring 1.5 to the floor value and you have "1", giving the chunk number 1.


We can try the same for the block number 3 :

3/4 = 0.75, meaning 0 to the floor value. So, the block 3 is in chunk 0.


But what we need is the position of this chunk, because the solution doesn't work in a 3D world. We have a chunk number 1 in every axis.


To fix that, multiply the chunk number by 4, you will have the position of the chunk for one axis.


Now let's add it to the code, go to the World script :

I won't optimize the code, just to make what i said clear and visible.

I created a new Method called "GetChunkAtPos". I gives back the chunk placed at the position we asked for. We make it static so we can get it from the Chunk script.


It's exactly the same as i said :

- First, we store each axis of the position in variables to work with each one of them separately.

- Then we divide them by the chunkSize.

- We bring them to the floor value.

- We get the final position by multiplying each of the axis by the chunkSize.

- Then we put them back into a Vector3

- With this new position, we find the chunk which is placed at the same position.

To do that, use a condition where we ask if the chunk we search at the position exists (while storing it in "foundchunk".

If it exists, we give it back.

- If we can't find anything, we return nothing.


Now let's find the outsider block :

Go back to the Chunk script in the BlockExistsAtPos method. Where we check if a block exists at a position.

Remember when we had to check if the position we were looking at was out of the chunk?

We will change this. Before, it returned False, meaning that there were no block in front of it. Now because we have neighbour chunks, there are blocks.

- First, we have to find the neighbour chunk. We will use the method we created in the World script.

We call it with the position of the actual chunk + the position we are looking at, which is outside.

- Then, we convert the value which is outside to find the position in the neighbour with a new method called "ConvertIndexToLocal".


Create this method :

It will convert each value we have for each axis.

If the value is -1 in the chunk we are looking, we must be at the edge of the neighbour.

If it is greater than the border of our chunk, it is at position 0 in the other neighbour.

Then we give back the converted value.



- After converting those values, we will check if the neighbour we called exists in the world.

If it does, we ask him if at the converted position x,y,z we are looking at, there is a block.

- If there is no chunk, we return "false".


Now you can test your game in Unity :

We have now fixed the inter-chunk detection. We will have a nice world looking good and optimized!


And we can play with our chunks again, without any problem and also with inter-chunk detection :


89 vues0 commentaire

Posts récents

Voir tout
bottom of page