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. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

Question Storing data for a grid based system.

Discussion in 'Scripting' started by Penkine, Sep 28, 2020.

  1. Penkine

    Penkine

    Joined:
    Jun 5, 2019
    Posts:
    15
    I have a grid where in each individual coordinate location it holds information on:

    The ground type

    The wall type
    IF - There is a wall

    The object type
    IF - There is an object
    AND IF - There is not a wall

    The pipe type
    IF - There is a pipe
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,797
    I am not sure what your question is here... just about data structures in general or did you have a specific issue?

    How to report problems productively in the Unity3D forums:

    http://plbm.com/?p=220

    Help us to help you.
     
  3. Penkine

    Penkine

    Joined:
    Jun 5, 2019
    Posts:
    15
    I wanna know the best way of storing grid data to be accessed by many scripts, the data would be in a matrix like
    [ [X, X, X]
    [X, X, X]
    [X, X, X] ]
    Where X is a struct with all the information for that spot
     
  4. Sphinks

    Sphinks

    Joined:
    Apr 6, 2019
    Posts:
    267
    Do you know how many data you will have at the end ?
    You can store it for example in a file where each line is one object with the comma separated values.

    So you can read that file line by line, create a new object for each line, split the values by , (comma) and set the the values to the object.

    But it´s not the best way if you have thousands of lines/data/objects.

    Hope i understood it correct and the answer helps you.
     
  5. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,797
    The best way will always be dependent on details such as how long you want to store it and how massive it is, how sparse it is, etc.

    But this just seems like a very straightforward "cells in a grid with stuff inside 'em."

    Generally store things in a class:

    https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/classes

    And you can either use a Dictionary indexed by a 2-dimensional custom key:

    https://docs.microsoft.com/en-us/dotnet/api/system.collections.generic.dictionary-2?view=netcore-3.1

    https://stackoverflow.com/questions/6999191/use-custom-object-as-dictionary-key

    Or just store it in a 2D array:

    https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/arrays/multidimensional-arrays

    or if you prefer, a jagged 2D array:

    https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/arrays/jagged-arrays

    Regardless of any choice above, FAR more important is to immediately push past the first steps of this, choose an approach (any approach is better than analysis paralysis) and start working with actual data so you can begin to evaluate which way might work best in your exact context, which none of us have access to here.
     
    Last edited: Sep 29, 2020
    Penkine likes this.
  6. Penkine

    Penkine

    Joined:
    Jun 5, 2019
    Posts:
    15
    The dictionary choice seems like the best option, how would I create a 2-dimensional custom key?
     
  7. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,797
    Did you read the stackoverflow link? I'm not sure I could explain it any better. What part are you having difficulty with?
     
  8. orionsyndrome

    orionsyndrome

    Joined:
    May 4, 2014
    Posts:
    3,043
    By assuming you know what you're doing, here are your options:
    a) you compute a 'flat' index
    b) you construct a value tuple
    c) you compute a hash with a custom hash function
    d) you compute a Cantor pairing value

    Without much hesitation, I'd always pick (a) in your case

    This is how to implement these
    a)
    int index = y * width + x;
    given that your width is fixed for each row, you end up with unique indice
    to reverse a flat index you have to do the following
    y = index / width;
    (<- this is an integer division, not an ordinary one!!)
    x = index % width;
    (<- this is a modulo remainder division)

    b)
    (int x, int y) key = (x, y);

    C# will generate a proper hash code for each value combination, but I'm not sure if it guarantees uniqueness for a very large set
    you don't have to reverse anything, the source values are accessible at all times, by doing
    key.x
    or
    key.y


    c)
    the most banal hash function would be
    int hash = (y << 16) | x;

    you will run into hash collisions if your x or y can be equal to or greater than 2^16 for this particular scenario
    (look up into proper hash generators online)
    you can't normally reverse a hash key cheaply, but in this banal scenario you actually can by doing
    int x = hash & 0xf, y = hash >> 16;


    d)
    Cantor pairing
    int pairing = unchecked(((x + y) * (x + y + 1) >> 1) + y);

    uniqueness is mathematically guaranteed (unless you hit an overflow)
    for reversing check the link