Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Voting for the Unity Awards are OPEN! We’re looking to celebrate creators across games, industry, film, and many more categories. Cast your vote now for all categories
    Dismiss Notice
  3. Dismiss Notice

How to access element 18692 without having 18693+ elements?

Discussion in 'Scripting' started by Deleted User, Aug 30, 2018.

  1. Deleted User

    Deleted User

    Guest

    So I'm making a voxel-based game, but I'm having a little trouble with the world generation. Let's say the player breaks a block located at cords 18692, 67, 8583. I already know where exactly the block is because the player hit something solid with a ray, so now I just have to say BreakBlock(blocks[18692, 67, 7583]). But oh wait, my blocks array cannot hold that much data as to match the position of the block that I'm trying to break, so the question is how do I even access/store a block with a position out of range of any array? can I perhaps set the array so that it does not start at 0, but maybe a few hundred less than what it ends at? I'm basically just trying to sync the array up with all the positions of the blocks currently active and generated around the player.

    Code (CSharp):
    1. //The method below will create a new block for an unexplored part of the world.
    2.  
    3. Block CreateNewBlock(int x, int y, int z){
    4.    blocks [18692, 67, 4895] == new Block (x, y, z);
    5. }
    6.  
    7. //Oh, wait, no it won't. Because having a total 6,130,321,780 elements in an array is completely unrealistic.
     
    Last edited by a moderator: Aug 30, 2018
  2. Avo

    Avo

    Joined:
    Dec 4, 2010
    Posts:
    236
    angrypenguin likes this.
  3. Deleted User

    Deleted User

    Guest

    As a whole I suppose, but I was just asking about one part of a voxel generation, to explain all of it would take hours. Thanks for the link.
     
  4. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    Normally you just build an array of arrays. You can convert a world position to an array position with a little bit of multiplication.

    Voxel engines normally handle things in chunks. An individual chunk only handles a reasonable amount of voxels. If you run out of chunks to play with, then you just add another layer of chunking on top.
     
    xVergilx, Ryiah and angrypenguin like this.
  5. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    15,504
    Sure, but to explain that part has loads of assumed knowledge on behalf of both the explainee and the explainer. There's not one right answer to this, and from your post alone we've no idea where you're up to or which of many, many possible approaches you're taking.

    Do you currently have a world this big with stuff in it that the player can hit? Or is this hypothetical? If you've got that world, how is that implemented?

    As one approach, for this you could use an offset. An array index always starts at 0 because of how computers work, but you can wrap it in an object that has some offset values that are applied to read/write operations on the underlying data. The offset is just a variable that gets subtracted from your indices before read/write operations, which you would do via a function.

    The thing is, I suspect that answer is missing the forest for the trees, so to speak. You're asking about the problem of addressing, but this is really a broader problem of "storing an arbitrarily large amount of spatially addressable data in a way that's efficient for a computer". For the particular problem of voxel worlds the common approach, per @Kiwasi's post, is "chunking".
     
  6. Deleted User

    Deleted User

    Guest

    Yes, I am indeed chunking the world, as in rendering large amounts of blocks as a single mesh. I do have an array of arrays of arrays, it's a 3-dimensional array. But like I said, I can't just enter the cords into it because it can't support that many elements.
     
  7. Joe-Censored

    Joe-Censored

    Joined:
    Mar 26, 2013
    Posts:
    11,847
    Isn't the maximum number of elements in an array the same as the maximum value of an int? Are your needs surpassing that?
     
  8. Antistone

    Antistone

    Joined:
    Feb 22, 2014
    Posts:
    2,833
    If you have a small number of things that you need to track, but the coordinates of where they're located might be really big, then that would be the "sparse array" problem. You wouldn't want to allocate memory for every possible coordinate, because the number of coordinates vastly exceeds the amount of actual data, so that would waste a lot of memory. Instead, you'd probably use something like a Dictionary that only allocates memory for the coordinates you actually use. Or, if the relevant coordinates are concentrated in a small range, maybe you'd have an array of 100 elements indexed from 18600 to 18700.

    However, if you actually have 18692 * 67 * 8583 separate individual voxels in your world, then the problem isn't that an array would waste space, it's that you've got too much stuff. You can't have any explicit representation of each individual voxel--no matter what kind of data structure you put them in--because there's too many of them.

    You'd need to have some kind of abstract representation that allows you to infer information about the voxels at specific coordinates without actually storing every voxel individually. Not just chunking for rendering, but chunking for how the voxels are represented in your computer's memory banks.

    That means you can't simply reference "the voxel located at (18692, 67, 8583)"--in an array or otherwise--because no such object exists in your computer's memory. You need to interact with whatever data structure you are using to abstractly represent your world.

    And how you do that really can't be answered without knowing a great deal of detail about how that abstract data structure works.
     
    angrypenguin likes this.
  9. Deleted User

    Deleted User

    Guest

    That's just for the length of the array, there is also stuff in it usually.

    I actually just spent several hours rewriting my system so that block data is now stored in individual chunks, while before all the blocks currently existing were located in a single 3-dimensional array. This should hopefully fix some of this accessing problem I'm having and make everything easier to work with. I also realized that there was no need to store a block's cords in its type, as if I'm able to access it then I must know the cords already in the first place, which leaves just the ID being held in the Block type, making it useless. So now I'm just using a short to represent every block, which should be far more efficient than the way I had it before.
     
  10. Joe-Censored

    Joe-Censored

    Joined:
    Mar 26, 2013
    Posts:
    11,847
    .net 4.5 removed the 2GB memory limit on the contents of arrays so you can take indexes all the way to max int (assuming available memory to hold it all). Not sure if the mono equivalent implemented that though, or if the OP is using the legacy backend.
     
  11. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    15,504
    That's the maximun number of elements you can index. The maximum number you can store is also dependent on available memory.

    Edit: Oops, looks like I somehow missed that being covered already .
     
    Last edited: Aug 31, 2018
  12. neoshaman

    neoshaman

    Joined:
    Feb 11, 2011
    Posts:
    6,466
    GUYS !!!! He is asking for the concept of spatial hash ...
    - He need to hash the global coordinate to the spatial hash (chunk) coordinate (position/Chunksize for chunk coordinate, then position%chunksize for chunk space coordinate).
    - Then he need a way to store change
    - then he need to remember that big voxel world are generally pcg, which mean data is implied by a formula, no need to store more than needed, you can just regenerate it and apply change
    - else he need to stream in and out data.
     
    Ryiah, JoeStrout and angrypenguin like this.
  13. Deleted User

    Deleted User

    Guest

    Ugh, something went very very wrong when assembling the chunk mesh.

    https://imgur.com/a/IQNkUSB

    Edit: Oh, somehow when I switched over some code, I mixed up which functions add which sides.
     
    Last edited by a moderator: Aug 31, 2018
  14. Deleted User

    Deleted User

    Guest

    Yeah, that's probably what I'm looking for.
     
  15. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,840
    You need, in short. a Dictionary.

    When I did this, I made a Vector3i struct, which is very similar to Vector3 but with ints instead of floats. And I gave it a hash method that basically just hashed the x, y, and z coordinates together. Then, you can use such structs as an index into a Dictionary, to get and set the chunk for any coordinates.

    Not really that complicated a question after all, I think. ;)
     
    Last edited: Aug 31, 2018
    Deleted User likes this.
  16. Deleted User

    Deleted User

    Guest

    Yes! I think this is just what I need. And I always thought that Dictionaries were useless...