Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 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 /
  • Help Room /
avatar image
0
Question by nitrogames79 · Dec 14, 2019 at 10:57 PM · crashvoxelchunks

Voxel Chunk error

I had been following a tutorial on voxel worlds until I got to a part where it started crashing every time I started the scene. As far as I can tell it only crashes when one of the world position coordinates are a negative, but I've been working for weeks on someway to fix it, but no matter what I do it always crashes. Here's the error data.

 StackOverflowException: The requested operation caused a stack overflow.
   at (wrapper managed-to-native) System.ValueType.InternalEquals(object,object,object[]&)
   at System.ValueType.DefaultEquals (System.Object o1, System.Object o2) [0x00031] in <7d97106330684add86d080ecf65bfe69>:0 
   at System.ValueType.Equals (System.Object obj) [0x00000] in <7d97106330684add86d080ecf65bfe69>:0 
   at System.Collections.Generic.ObjectEqualityComparer`1[T].Equals (T x, T y) [0x00010] in <7d97106330684add86d080ecf65bfe69>:0 
   at System.Collections.Generic.Dictionary`2[TKey,TValue].FindEntry (TKey key) [0x00056] in <7d97106330684add86d080ecf65bfe69>:0 
   at System.Collections.Generic.Dictionary`2[TKey,TValue].TryGetValue (TKey key, TValue& value) [0x00000] in <7d97106330684add86d080ecf65bfe69>:0 
   at World.GetChunk (System.Int32 x, System.Int32 y, System.Int32 z) [0x00066] in C:\Users\maria\Voxel Stuff 2\Assets\WorldData\World.cs:39 
   at World.GetBlock (System.Int32 x, System.Int32 y, System.Int32 z) [0x00001] in C:\Users\maria\Voxel Stuff 2\Assets\WorldData\World.cs:47 
   at Chunk.GetBlock (System.Int32 x, System.Int32 y, System.Int32 z) [0x00031] in C:\Users\maria\Voxel Stuff 2\Assets\WorldData\Chunk.cs:79 
   at World.GetBlock (System.Int32 x, System.Int32 y, System.Int32 z) [0x00017] in C:\Users\maria\Voxel Stuff 2\Assets\WorldData\World.cs:49 
   at Chunk.GetBlock (System.Int32 x, System.Int32 y, System.Int32 z) [0x00031] in C:\Users\maria\Voxel Stuff 2\Assets\WorldData\Chunk.cs:79 
   at World.GetBlock (System.Int32 x, System.Int32 y, System.Int32 z) [0x00017] in C:\Users\maria\Voxel Stuff 2\Assets\WorldData\World.cs:49 
   at Chunk.GetBlock (System.Int32 x, System.Int32 y, System.Int32 z) [0x00031] in C:\Users\maria\Voxel Stuff 2\Assets\WorldData\Chunk.cs:79 
   at World.GetBlock (System.Int32 x, System.Int32 y, System.Int32 z) [0x00017] in C:\Users\maria\Voxel Stuff 2\Assets\WorldData\World.cs:49 

It continues like this until it ends. World Script: using System.Collections; using System.Collections.Generic; using UnityEngine;

 public class World : MonoBehaviour
 {
     public GameObject chunkPrefab;
 
     public Dictionary<WorldPos, Chunk> chunks = new Dictionary<WorldPos, Chunk>();
 
     public bool ChunkExist;
 
     public int blocksGetSet;
 
     void Start(){
         blocksGetSet = Chunk.chunkSize;
         for (int x = -1; x < 1; x++){
             for (int y = -1; y < 1; y++){
                 for (int z = -1; z < 1; z++){
                    CreateChunk(x * 16, y * 16, z * 16);
                 }
             }
         }
     }
 
     public Chunk GetChunk(int x, int y, int z){
         WorldPos pos = new WorldPos();
         int multiple = Chunk.chunkSize;
         if (x < 0){
             pos.x = Mathf.FloorToInt(x / multiple) * multiple;
         }
         if (x < 0){
             pos.y = Mathf.FloorToInt(y / multiple) * multiple;
         }
         if (x < 0){
             pos.z = Mathf.CeilToInt(z / multiple) * multiple;
         }
         Chunk chunkContainer = null;
         chunks.TryGetValue(pos, out chunkContainer);
 
         return chunkContainer;
 
     }
 
     public Block GetBlock(int x, int y, int z)
      {
         Chunk containerChunk = GetChunk(x, y, z);
         if (containerChunk != null) {
             Block block = containerChunk.GetBlock(x - containerChunk.pos.x, y - containerChunk.pos.y, z - containerChunk.pos.z);
   
             return block;
         }
         else {
             return new BlockAir();
         }
   
     }
 
     public void SetBlock(int xi, int x, int yi, int y, int zi, int z, Block block){
         int xii = xi + x;
         int yii = yi + y;
         int zii = zi + z;
         Chunk chunk = GetChunk(xii, yii, zii);
         
         if (chunk != null){
             int newx = Chunk.chunkSize;
             int newy = Chunk.chunkSize;
             int newz = Chunk.chunkSize;
             
             if (x == -1){
                 newx = -Chunk.chunkSize;
             }
             if (y == -1){
                 newx = -Chunk.chunkSize;
             }
             if (z == -1){
                 newx = -Chunk.chunkSize;
             }
             if (x > -1 && x < Chunk.chunkSize){
                 newx = 0;
             }
             if (y > -1 && y < Chunk.chunkSize){
                 newy = 0;
             }
             if (z > -1 && z < Chunk.chunkSize){
                 newz = 0;
             }
             chunk.SetBlock(x - newx, y - newy, z - newz, block);
             chunk.update = true;
         }
     }
 
     public void CreateChunk(int x, int y, int z){
         WorldPos worldPos = new WorldPos(x, y, z);
 
         Chunk chunk = null;
         chunks.TryGetValue(worldPos, out chunk);
         ChunkExist = false;
         if (chunk != null){
             ChunkExist = true;
         }
         if (ChunkExist == false){
             
         GameObject newChunkObject = Instantiate(chunkPrefab, new Vector3(x, y, z), Quaternion.Euler(Vector3.zero)) as GameObject;
 
         Chunk newChunk = newChunkObject.GetComponent<Chunk>();
 
         newChunk.pos = worldPos;
         newChunk.world = this;
 
         chunks.Add(worldPos, newChunk);
         }
         
 
         
     }
 
     public void DestroyChunk(int x, int y, int z){
         Chunk chunk = GetChunk(x, y, z);
         if (chunk != null){
             Object.Destroy(chunk.gameObject);
             chunks.Remove(new WorldPos(x, y, z));
         }
     }
 
     
 }

and the Chunk Script

 using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
 [RequireComponent(typeof(MeshRenderer))]
 [RequireComponent(typeof(MeshFilter))]
 [RequireComponent(typeof(MeshCollider))]
 
 public class Chunk : MonoBehaviour
 {   
     MeshFilter filter;
     MeshCollider coll;
 
     public int octaves = 4;
     public int seed = 350;
     //Size of the Chunk.
     public const int chunkSize = 16;
 
     public float scale = 7.2f;
     public float persistance = 0.5f;
     public float lacunairty = 2f;
 
     public Vector3 offset;
 
     public bool update = true;
 
     public World world;
     public WorldPos pos;
 
     private Block[ , , ] blocks = new Block[chunkSize, chunkSize, chunkSize];
 
     private float[ , , ] chunkDensity = new float[chunkSize, chunkSize, chunkSize];
 
     void Start(){
         filter = gameObject.GetComponent<MeshFilter>();
         coll = gameObject.GetComponent<MeshCollider>();
         offset.x = pos.x;
         offset.y = pos.y;
         offset.z = pos.z;
         octaves = 4;
         seed = 350;
         scale = 7.2f;
         persistance = 0.5f;
         lacunairty = 2f;
         chunkDensity = Simple3dNoise.GenerateWorld(chunkSize, octaves, seed, scale, persistance, lacunairty, offset);
         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] = new BlockAir();
                     if (chunkDensity[x, y, z] > 0.38){
                         blocks[x, y, z] = new Block();
                     }    
                 }
             }
         }
     }
 
     void Update(){
         if (Input.GetKeyDown(KeyCode.P)){
             UpdateChunk();
         }
         if (update){
             update = false;
             UpdateChunk();
         }
     }
 
     public static bool InRange(int index){
         if (index < 0 || index >= chunkSize){
             return false;
         }
         return true;
     }
 
     public Block GetBlock(int x, int y, int z){
         if (InRange(x) && InRange(y) && InRange(z)){
             return blocks[x, y, z];
         }
         else{
             return world.GetBlock(pos.x + x, pos.y + y, pos.z + z);
         }  
     }
 
     public void SetBlock(int x, int y, int z, Block block){
         if (InRange(x) && InRange(y) && InRange(z)){
             blocks[x, y, z] = block;
         }
         else{
             world.SetBlock(pos.x, x, pos.y, y, pos.z, z, block);
         }
         
     }
 
     public void UpdateChunk(){
         MeshData meshData = new MeshData();
         for (int x = 0; x < chunkSize; x++){
             for (int y = 0; y < chunkSize; y++){
                 for (int z = 0; z < chunkSize; z++){
                     meshData = blocks[x, y, z].BlockData(this, x, y, z, meshData);
                 }
             }
         }
         RenderChunk(meshData);
     }
 
     public void RenderChunk(MeshData meshData){
         filter.mesh.Clear();
         filter.mesh.vertices = meshData.vertices.ToArray();
         filter.mesh.triangles = meshData.triangles.ToArray();
 
         filter.mesh.uv = meshData.UVs.ToArray();
         filter.mesh.RecalculateNormals();
     }
 }

If anything else is needed to figure it out I'll add it.

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 Bunny83 · Dec 14, 2019 at 11:14 PM

Well, it would be interesting how WorldPos looks like. However the actual reason is your World.GetChunk method. You do some strange things in there. First of all the 3 if statements all check if x is negative. Probably a copy&paste error. However regardless of that I don't quite get the point of those if statements. You create a new empty "pos". Then only when the x coordinate is negative you actually set the x / y / z component to the position passed. That means if x is positive then you will not set any of the components at all so you most likely always get the chunk (0,0,0). Since your two GetBlock method (one in World, one in Chunk) calls each other when the coordinate does not fall within the same chunk you get an infinite recursion since each time you try to get a chunk to the right but you always return the same.


I would also recommend to actually store the chunk position and not the lowest block position in block coordinates. So a chunk coordinate of (2,0) would start at (2*chunksize, 0). Also you should probably centralize the chunk coordinate alignment and rethink your logic because at the moment it makes no sense at all.

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

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

128 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

Related Questions

Unity Player crashes on a scene with Video Player. 1 Answer

Photon crash 1 Answer

unity crashes when i run a empty foreach loop 0 Answers

Unity Crashes When Adding Script To GameObject 0 Answers

the name 'chunk' does not exist in the current context 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