Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
15
Question by CarlLawl · Oct 19, 2011 at 12:02 AM · tutorialminecraftchunks

[Tutorial] Minecraft Chunks

After noticing the vast amount of help for Minecraft clones I've decided to post up a few tutorials explaining different aspects of building one. In this section I'll try my best to show you how to create "Chunks" although I'll apologise for my explanations now as I'm awful at explaining.

I would also like to credit the MinePackage located HERE as most of the code has been taken and rewritten out from this. If you'd like to learn more there is another thread which you can check out HERE

If people like this then I'll make a few more, if any of my information is incorrect then I apologise, let me know and I'll update it, or if you have a better explanation or extra info just add it as an answer.

So what is a "Chunk" then?

In Minecraft think of the thousands of blocks there are to your disposal, now what would happen if we were to render them all every frame? Well our FPS would be non existant. So one way we can help speed things up is to slice our level in to manageable "Chunks".

How would this speed up the game?

Instead of rendering the entire level over and over, we could just take the chunks within a certain radius of our player and only render those, not only does this speed things up but it also means we aren't working with the entire level only a small portion of it. This is bordering another aspect but what if we wanted to find out what blocks the player is able to see? Rather than doing this for the entire level every frame we can just check the surrounding chunks.

What will I learn for this then?

Fingers crossed you will be able to create empty chunks in your world to a size you choose. This is merely showing you how chunks work and how to create them, they have no functionality. I'm posting this because it took me a while to scan examples to learn how they work.

Now I know chunks, what next?

Well I'm still learning myself but I would recommend looking up Octrees, Procedural Meshes, Texture atlas' and Perlin Noise (Hopefully if I get time I'll post up some stuff about these)

WorldGameObject.cs attaches to an empty GameObject

WorldGameObject PasteBin

WorldGameObject.cs

 using UnityEngine;
 using System.Collections;
 
 public class WorldGameObject : MonoBehaviour {
     
     private WorldData world = new WorldData();                    // Holds all the data about our world
     
     public Transform chunkPrefab;                                // A template of a chunk
     public Transform[,,] chunkGO;                                // A list of our chunks coords
 
     void Start () {
         // So we start by initializing a grid for our chunks
         // In our world data script we run a function that
         // Creates a 3 dimensional array and sets the coords
         // For each Chunk
         world.InitChunkGrid();
         
         // After initializing our grid for our chunks
         // We can now go ahead and instantiat our chunks
         // Referencing their Transform
         CreateChunks();
     }
     
     private void CreateChunks()
     {
         // This will only contain the locations of our chunks
         // The actually chunk data gets stored in our ChunkData script
         chunkGO = new Transform[world.ChunksX,world.ChunksY,world.ChunksZ];
         
         // 3 for loops, x,y,z each increment will represent a chunk
         // We only want to go as high as the amount of chunks in our
         // World so we set the loop amount as ChunksX,ChunksY,ChunksZ
         for (int x = 0; x < world.ChunksX; x++)
         {
             for (int y = 0; y < world.ChunksY; y++)
             {
                 for (int z = 0; z < world.ChunksZ; z++)
                 {
                     // We get the chunk from the array located at x,y,z
                     // And store it as the current chunk we're working on
                     ChunkData curChunk = world.chunks[x, y, z];
                     
                     // Here we create a Vector3 of where the chunk will be placed
                     // the x position on our vector3 is the current chunk's x coord multiplied
                     // By the chunk width for example if curChunk is 2 we multiply it by our ChunkWidth,
                     // Which in this case would be 32 because our chunks are 32x32x128 meaning
                     // the chunks x position would be 64, we don't need to worry about Y because
                     // Our chunk height is 1, then we do the same on the Z axis
                     Vector3 chunkInstPos = new Vector3(curChunk.X * world.ChunkWidth, 0, curChunk.Y * world.ChunkHeight);
                     
                     // Now that we have where to we want put our chunk lets create a chunk instance
                     Transform chunkInst = Instantiate(chunkPrefab, chunkInstPos, Quaternion.identity) as Transform;
                     
                     // After creating an instance of a chunk lets set the parent to our World GameObject
                     chunkInst.parent = transform;
                     
                     // Lets rename the chunk to something more managable
                     // In our ChunkData script is a function called ToString
                     // This basically returns a string of the chunks position
                     // It will return something like Chunk ( 1,0,1 )
                     chunkInst.name = curChunk.ToString();
                     
                     // Now our chunk exists lets make a reference of it's
                     // Position by adding it to our array
                     chunkGO[x, y, z] = chunkInst;
                 }
             }
         }
     }
 }

WorldData.cs doesn't need to be attached to anything

WorldData PasteBin

WorldData.cs

 using System.Collections;
 
 public class WorldData  {
     
     private int chunkWidth = 32, chunkHeight = 128, chunkDepth = 32;        // The dimensions of each chunk in blocks, so each chunk is 32 blocks in width and depth but 128 blocks in height
     private int chunksX = 8, chunksY = 1, chunksZ = 8;                        // How many chunks we want to generate in the world along each axis
     
     public ChunkData[,,] chunks;                                            // And array of our chunks so we can keep track of them
     
     public const int BottomChunkBorderRow = 0, LeftChunkBorderColumn = 0;
     
     public void InitChunkGrid()
     {
         // Lets initialize our array where our chunk data will be stored
         chunks = new ChunkData[chunksX,chunksY,chunksZ];
         
         // Our for loops so we can iterate through and set our chunk
         // Position in the array
         for (int x = LeftChunkBorderColumn; x <= RightChunkBorderColumn; x++)
         {
             for (int y = BottomChunkBorderRow; y <= TopChunkBorderRow; y++)
             {
                 for (int z = 0; z < chunksZ; z++)
                 {
                     // Create a new set of ChunkData at x,y,z
                     chunks[x, y, z] = new ChunkData(x, y, z);
                 }
             }
         }
     }
     
     // Chunk width,height,depth Functions just allow us
     // To get and set the value of our vars because they're private
     public int ChunkWidth
     {
         get { return chunkWidth; }
         set { chunkWidth = value; }
     }
     
     public int ChunkHeight
     {
         get { return chunkHeight; }
         set { chunkHeight = value; }
     }
     
     public int ChunkDepth
     {
         get { return chunkDepth; }
         set { chunkDepth = value; }
     }
     
     // Chunks X,Y,Z Functions just allow us
     // To get and set the value of our vars because they're private
     public int ChunksX
     {
         get { return chunksX; }
         set { chunksX = value; }
     }
     
     public int ChunksY
     {
         get { return chunksY; }
         set { chunksY = value; }
     }
     
     public int ChunksZ
     {
         get { return chunksZ; }
         set { chunksZ = value; }
     }
     
     public int TopChunkBorderRow
     {
         get { return chunksY - 1; }
     }
 
     public int RightChunkBorderColumn
     {
         get { return chunksX - 1; }
     }
 }

ChunkData.cs doesn't need to be attached to anything

ChunkData PasteBin

ChunkData.cs

 using System.Collections;
 
 public class ChunkData {
     
     private int x,y,z;                            // Create 3 ints called x,y,z to store our position in our WorldData array
     
     // When ever our chunkData, we will send in
     // The position it will be stored in the WorldData array
     public ChunkData(int _x, int _y, int _z)
     {
         x = _x;
         y = _y;
         z = _z;
     }
     
     // X,Y,Z Functions just allow us to get and set the value
     // Of our vars x,y,z because they're private
     public int X
     {
         get { return x; }
         set { x = value; }
     }
 
     public int Y
     {
         get { return y; }
         set { y = value; }
     }
 
     public int Z
     {
         get { return z; }
     }
     
     // We will use this when renaming our chunk
     // So it is something more readable and managable
     // Instead of having them all name Chunk(clone)
     public override string ToString()
     {
         return string.Format("Chunk ( {0},{1},{2} )", x,y,z);
     }
 }


Comment
Add comment · Show 12
10 |3000 characters needed characters left characters exceeded
â–¼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image DaveA · Oct 19, 2011 at 12:03 AM 2
Share

I predict thousands of views on this topic

avatar image DevonJavaScript · Oct 19, 2011 at 12:11 AM 6
Share

Sir I do believe this is meant for the forums, not a questioning site, considering its a tutorial.

avatar image syclamoth · Oct 19, 2011 at 12:26 AM 1
Share

Can we mark this a community wiki entry?

Although, I doubt this will stop the endless questions about it- people find it easier to ask a new question than to use a search function.

avatar image gfr · Oct 19, 2011 at 11:41 AM 3
Share

To fit the QA format, why not just make it a question "How to do $$anonymous$$ecraft chunks?" and provide what you have above as an answer? You could even just give a rough overview and point to the forums for the full tutorial.

avatar image gfr · Oct 19, 2011 at 06:47 PM 1
Share

Nothing is keeping you from editing the question and then posting your answer :)

Show more comments

3 Replies

· Add your reply
  • Sort: 
avatar image
0

Answer by D1AM0ND4UN73R · Aug 22, 2012 at 09:25 AM

This is not a question. This site is only for questions, not tutorials.

Comment
Add comment · Show 3 · Share
10 |3000 characters needed characters left characters exceeded
â–¼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image AlucardJay · Aug 22, 2012 at 09:25 AM 2
Share

Please don't post comments as answers. Post comments by clicking the [add new comment] button, a window then open for you to type in. Answer fields are for answers only, as this is a knowledge base.

avatar image CarlLawl · Aug 22, 2012 at 11:07 AM 2
Share

Are you a retard? I made this post like 2 years ago, if you don't have a proper answer fuck off, this site is only for questions and answers.

avatar image james_170482 · Jul 29, 2014 at 11:44 AM 0
Share

CarlLawl you took the time to give back to this community and i don't see a single thank you, just moaning people!

Well THAN$$anonymous$$ YOU, very helpful.

avatar image
-1

Answer by drollestprawn4 · Dec 11, 2020 at 08:44 PM

This site is for people to post questions and then other people to answer them not to post an answer to a question that wasn't asked.

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
â–¼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image
0

Answer by Vaughnderrick · May 30, 2017 at 07:41 AM

Copy This Code Here:

 using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
 
 public class Block
 {
     public int type;
     public bool vis;
 
     public Block(int t, bool v)
     {
         type = t;
         vis = v;
     }
 }
 
 public class Woldcreator : MonoBehaviour
 {
 
     public static int width = 128;
     public static int depth = 128;
     public static int height = 128;
     public int heightSacale = 20;
     public float detailScale = 25.0f;
 
 
     public GameObject BlockDirtStone01;
     public GameObject BlockGrass01;
     public GameObject Blocksnow01;
 
     Block[,,] worldBlock = new Block[width, height, depth];
 
     void Start()
     {
         int seed = (int) Network.time * 10;
         for(int z = 0; z < depth; z++)
         {
             for (int x = 0; x < width; x++)
             {
                 int y = (int) (Mathf.PerlinNoise((x+seed)/detailScale, (z+seed)/detailScale) * heightSacale);
                 Vector3 blockPos = new Vector3(x,y,z);
 
                 CreateBlock(y, blockPos, true);
                 while(y > 0)
                 {
                     y--;
                     blockPos = new Vector3(x, y, z);
                     CreateBlock(y, blockPos, false);
                 }
             }
         }
     }
 
     void CreateBlock(int y, Vector3 blockPos, bool create)
     {
         if (y > 15)
 
         {
             if(create)
                  Instantiate(Blocksnow01, blockPos, Quaternion.identity);
             worldBlock[(int)blockPos.x, (int)blockPos.y, (int)blockPos.z] = new Block(1, create);
         }
         else if (y > 5)
         {
             if(create)
                  Instantiate(BlockGrass01, blockPos, Quaternion.identity);
             worldBlock[(int)blockPos.x, (int)blockPos.y, (int)blockPos.z] = new Block(2, create);
         }
         else
         {
             if(create)
                 Instantiate(BlockDirtStone01, blockPos, Quaternion.identity);
             worldBlock[(int)blockPos.x, (int)blockPos.y, (int)blockPos.z] = new Block(3, create);
         }
     }
 
     void DrawBlock(Vector3 blockPos)
     {
         if (blockPos.x < 0 || blockPos.x >= width || blockPos.y < 0 || blockPos.y >= height || blockPos.z < 0 || blockPos.z >= depth)return;
 
 
         if (!worldBlock[(int)blockPos.x, (int)blockPos.y, (int)blockPos.z].vis)
         {
 
                 worldBlock[(int)blockPos.x, (int)blockPos.y, (int)blockPos.z].vis = true;
             if (worldBlock[(int)blockPos.x, (int)blockPos.y, (int)blockPos.z].type == 1)
                 Instantiate(Blocksnow01, blockPos, Quaternion.identity);
 
             else if (worldBlock[(int)blockPos.x, (int)blockPos.y, (int)blockPos.z].type == 2)
                 Instantiate(Blocksnow01, blockPos, Quaternion.identity);
 
             else if (worldBlock[(int)blockPos.x, (int)blockPos.y, (int)blockPos.z].type == 3)
                 Instantiate(Blocksnow01, blockPos, Quaternion.identity);
 
             else
                 worldBlock[(int)blockPos.x, (int)blockPos.y, (int)blockPos.z].vis = false;
             }
         }
     //ok
     void Update()
     {
         if(Input.GetMouseButtonDown(0))
         {
             RaycastHit hit;
             Ray ray = Camera.main.ScreenPointToRay(new Vector3(Screen.width / 2.0f, Screen.height / 2.0f, 0));
             // hinter hit gibt der wert die reich weite an z.b 4.0f wie weit der char Blöcke abbauen kann von seinen stand punkt aus
             if (Physics.Raycast(ray, out hit, 4.0f))
             {
                 Destroy(hit.transform.gameObject);
     }
     else if (Input.GetMouseButtonDown(1)) {
  RaycastHit hit;
  Ray ray = Camera.main.ScreenPointToRay (new Vector3 (Screen.width / 2f, Screen.height / 2f, 0));
  if (Physics.Raycast (ray, out hit, 50f)) {
   Vector3 newBlockPos = hit.transform.position;
   newBlockPos += hit.normal;
    CreateBlock ((int)newBlockPos.y, newBlockPos, true);
         }
     }
 }
 }

It Will Create Small Minecraft Chuncks

Block Adds -Snow -Grass -Sand

Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
â–¼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image clabe45 · Dec 23, 2018 at 04:08 AM 0
Share

Care to explain?

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

14 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Multiple Cars not working 1 Answer

Object doen't move even though i did according lesson 1 Answer

Roll a Ball tutorial error 4 Answers

Tag: Siren is not defined? (Stealth Tutorial) 2 Answers

I am new and need help 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges