Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
2 captures
13 Jun 22 - 14 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
0
Question by Random1User · Jan 02 at 02:09 PM · voxelminecraftblockchunk

What to do to make the chunk check other chunks?

I am working on a Minecraft clone and I have done chunk generation.

Chunk.cs:

 using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
 
 public class Chunk : MonoBehaviour
 {
     Mesh mesh;
     public MeshFilter meshFilter;
 
     public static int chunkSize = 16;
 
     public Block.BlockType[,,] blocks;
 
     public bool isUpdate = false;
 
     public static int count;
 
     private void Start()
     {
         blocks = new Block.BlockType[chunkSize, chunkSize, chunkSize];
 
         for (int x = 0; x < chunkSize; x++)
         {
             for (int y = 0; y < chunkSize; y++)
             {
                 for (int z = 0; z < chunkSize; z++)
                 {
                     blocks[x, y, z] = Block.BlockType.air;
                 }
             }
         }
 
         blocks[8, 8, 8] = Block.BlockType.stone;
 
         isUpdate = true;
     }
 
     private void Update()
     {
         if(isUpdate)
         {
             isUpdate = false;
             ChunkUpdate();
         }
     }
 
     public Block.BlockType GetBlock(int x, int y, int z)
     {
         return blocks[x, y, z];
     }
 
     public void ChunkUpdate()
     {
         for (int x = 0; x < chunkSize; x++)
         {
             for (int y = 0; y < chunkSize; y++)
             {
                 for (int z = 0; z < chunkSize; z++)
                 {
                     Block.RenderBlock(x, y, z, this);
                 }
             }
         }
 
         mesh = new Mesh();
 
         meshFilter.mesh.Clear();
         meshFilter.mesh.vertices = Block.vertices.ToArray();
         meshFilter.mesh.triangles = Block.triangles.ToArray();
 
         meshFilter.mesh.RecalculateNormals();
 
         count = 0;
     }
 }

Block.cs

 using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
 
 public static class Block
 {
     public enum BlockType
     {
         air,
         stone,
 
     }
 
     public static List<Vector3> vertices = new List<Vector3>();
     public static List<int> triangles = new List<int>();
 
     public static void RenderBlock(int x, int y, int z, Chunk chunk)
     {
         if (chunk.GetBlock(x, y, z) != BlockType.air)
         {
             if (!isSolid(x, y + 1, z, chunk))
             {
                 vertices.Add(new Vector3(0, 1, 0) + new Vector3(x, y, z));
                 vertices.Add(new Vector3(0, 1, 1) + new Vector3(x, y, z));
                 vertices.Add(new Vector3(1, 1, 1) + new Vector3(x, y, z));
                 vertices.Add(new Vector3(1, 1, 0) + new Vector3(x, y, z));
 
                 AddTriangles();
             }
 
             if (!isSolid(x, y - 1, z, chunk))
             {
                 vertices.Add(new Vector3(0, 0, 0) + new Vector3(x, y, z));
                 vertices.Add(new Vector3(1, 0, 0) + new Vector3(x, y, z));
                 vertices.Add(new Vector3(1, 0, 1) + new Vector3(x, y, z));
                 vertices.Add(new Vector3(0, 0, 1) + new Vector3(x, y, z));
 
                 AddTriangles();
             }
 
             if (!isSolid(x, y, z + 1, chunk))
             {
                 vertices.Add(new Vector3(0, 0, 1) + new Vector3(x, y, z));
                 vertices.Add(new Vector3(1, 0, 1) + new Vector3(x, y, z));
                 vertices.Add(new Vector3(1, 1, 1) + new Vector3(x, y, z));
                 vertices.Add(new Vector3(0, 1, 1) + new Vector3(x, y, z));
 
                 AddTriangles();
             }
 
             if (!isSolid(x, y, z - 1, chunk))
             {
                 vertices.Add(new Vector3(0, 0, 0) + new Vector3(x, y, z));
                 vertices.Add(new Vector3(0, 1, 0) + new Vector3(x, y, z));
                 vertices.Add(new Vector3(1, 1, 0) + new Vector3(x, y, z));
                 vertices.Add(new Vector3(1, 0, 0) + new Vector3(x, y, z));
 
                 AddTriangles();
             }
 
             if (!isSolid(x + 1, y, z, chunk))
             {
                 vertices.Add(new Vector3(1, 0, 0) + new Vector3(x, y, z));
                 vertices.Add(new Vector3(1, 1, 0) + new Vector3(x, y, z));
                 vertices.Add(new Vector3(1, 1, 1) + new Vector3(x, y, z));
                 vertices.Add(new Vector3(1, 0, 1) + new Vector3(x, y, z));
 
                 AddTriangles();
             }
 
             if (!isSolid(x - 1, y, z, chunk))
             {
                 vertices.Add(new Vector3(0, 0, 0) + new Vector3(x, y, z));
                 vertices.Add(new Vector3(0, 0, 1) + new Vector3(x, y, z));
                 vertices.Add(new Vector3(0, 1, 1) + new Vector3(x, y, z));
                 vertices.Add(new Vector3(0, 1, 0) + new Vector3(x, y, z));
 
                 AddTriangles();
             }
         }
     }
 
     public static void AddTriangles()
     {
         triangles.Add((Chunk.count * 4) + 0);
         triangles.Add((Chunk.count * 4) + 1);
         triangles.Add((Chunk.count * 4) + 2);
         triangles.Add((Chunk.count * 4) + 0);
         triangles.Add((Chunk.count * 4) + 2);
         triangles.Add((Chunk.count * 4) + 3);
 
         Chunk.count++;
     }
 
     public static bool isSolid(int x, int y, int z, Chunk chunk)
     {
         if(chunk.GetBlock(x, y, z) == BlockType.air)
         {
             return false;
         }
 
         else
         {
             return true;
         }
     }
 }

There are two scripts, Block.cs contains information about blocks, and Chunk.cs generates a chunk. Everything works well, but when I generate a block on the border of a chunk, it gives an error. Block.cs also checks adjacent blocks, if the adjacent block is air, then the side of the block is rendered, otherwise it is not, this chunk is optimized in this way. But the block does not check adjacent blocks outside the chunk. This problem made it difficult for me to create a Minecraft clone. I would be grateful if you have the opportunity to help me with this.

Comment
Add comment
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

1 Reply

· Add your reply
  • Sort: 
avatar image
0

Answer by Llama_w_2Ls · Jan 02 at 04:44 PM

I use one function to do this called IsEmptyAt which determines if a block is of type air, at a position in the chunk. It also checks neighbouring chunks (if they exist) if the block position is out of bounds.


 bool IsEmptyAt(Vector3Int neighbourPos, Vector3Int blockPos, Vector2Int chunkPos)
 {
     // Locate neighbour in chunk
     if (!Blocks.OutOfBounds(neighbourPos))
         return Blocks[neighbourPos].Type == BlockType.Air;
 
     var chunkOffset = (neighbourPos - blockPos) * World.instance.ChunkSize;
 
     // Block isn't in any chunk (above the sky and below the ground)
     if (chunkOffset.y != 0)
         return true;
 
     // Neighbour chunk = current chunk + offset
     var neighbourChunkPos = chunkPos + new Vector2Int(chunkOffset.x, chunkOffset.z);
 
     // Block doesn't exist
     if (!World.instance.Chunks.ContainsKey(neighbourChunkPos))
         return true;
 
     var neighbourChunk = World.instance.Chunks[neighbourChunkPos];
 
     var neighbourBlockPos = neighbourPos + new Vector3Int(chunkPos.x, 0, chunkPos.y) - new Vector3Int(neighbourChunkPos.x, 0, neighbourChunkPos.y);
     var neighbourBlock = neighbourChunk.Blocks[neighbourBlockPos];
 
     return neighbourBlock.Type == BlockType.Air;
 }



The first thing it does is if the block isn't out of the bounds of the chunk (which can be done by checking the position with its dimensions) then just return the type of the block in the chunk. This is a simple array lookup.


Else, it needs to find which chunk the block is actually in, since it is out of bounds. To find the chunk, you need to store all chunks generated in a dictionary in some World class. This can be referenced using a singleton, which I am using.


If the chunk is out of bounds on the y, I return empty, since chunks only extend infinitely on the x and z. Not the y.


Then, the neighbour chunk position is found, and therefore the chunk (from the World dictionary). If the chunk doesn't exist, I return empty.


Finally, I do some math to find the right block, and return its type. Hope that helps.


I have basic chunk generation in my minecraft clone. If you want to see it, I can upload it to a git directory later. @Random1User

Comment
Add comment · Show 2 · 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 Random1User · Jan 03 at 01:07 PM 0
Share

Thanks for the answer! I would like to see the source code of your clone

avatar image Llama_w_2Ls Random1User · Jan 04 at 07:08 PM 0
Share

Check out my github repo. I only uploaded the assets folder with the scene. That should be enough, if you copy it into a new unity project. @Random1User

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

133 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 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 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 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 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 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 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 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 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 avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Minecraft block placing/ block building - how to? 2 Answers

Voxel C# source problems. 1 Answer

map generation issues 0 Answers

This script really makes my game lag! 1 Answer

Question about slideScrolling Voxels 0 Answers


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