Search Unity

2D Arrays in C#

Discussion in 'Scripting' started by mattimus, Jul 17, 2010.

  1. mattimus

    mattimus

    Joined:
    Mar 8, 2008
    Posts:
    576
    I am trying to declare a public multidimensional array that I can access through the editor. However it would appear that only single dimension arrays are usable through the property inspector. Am I declaring these wrong, or are multidimensional arrays just not usable in the inspector?

     
  2. Dreamora

    Dreamora

    Joined:
    Apr 5, 2008
    Posts:
    26,601
    they will not show up in the editor, thats correct.

    you see normal arrays 1D and list<..> (on the desktop) but no higher order ones
     
    feyyd likes this.
  3. mattimus

    mattimus

    Joined:
    Mar 8, 2008
    Posts:
    576
    That really sucks.

    I'm working up a prototype for a game that has gameobject tiles within a rectangular grid of [row, col]. The tiles exist in the scene and I need to assign references them to a tile controller. The controller will apply changes to all tiles in one row or one column while leaving the rest of the tiles alone.

    I suppose I could declare a 1D array and set up methods for getting / setting row and col for the tiles, but that's a huge pain in the ass.

    Something like:
    Code (csharp):
    1. int GetArrayIndex(row, col)
    2. {
    3.     return (row + col*numRows);
    4. }
     
  4. Jesse Anders

    Jesse Anders

    Joined:
    Apr 5, 2008
    Posts:
    2,857
    Using a 1-d array with access functions for 2-d indexing is actually a pretty common solution to this problem, and has the advantage of (potentially) better cache coherency and less fragmentation (although that may not matter in this context).

    However, I think you can probably get the effect of a 'real' 2-d array by creating an array of objects, each of which represents one row. I tried the following:

    Code (csharp):
    1. [System.Serializable]
    2. public class Row
    3. {
    4.     public int[] data;
    5. };
    6. public Row[] test = new Row[3];
    And it seemed to work. (I haven't tried it, but by overloading the [] operator for the Row class, you may even be able to get the effect of 'standard' 2-d indexing, e.g. map[2][2].)
     
  5. mattimus

    mattimus

    Joined:
    Mar 8, 2008
    Posts:
    576
    Thanks Jesse. I managed to get a working setup based off your example.

     
  6. Ntero

    Ntero

    Joined:
    Apr 29, 2010
    Posts:
    1,436
    You can streamline it by allowing Jagged array syntax:
    Code (csharp):
    1.  
    2. [System.Serializable]
    3. public class StringArray
    4. {
    5.     public string[] names;
    6.    
    7.     public string this [int index]
    8.     {
    9.         get
    10.         {
    11.             return names[index];
    12.         }
    13.         set
    14.         {
    15.             names[index] = value;
    16.         }
    17.     }
    18. };
    19.  
    20. public class TestClass : MonoBehaviour
    21. {
    22.  
    23.     StringArray[] stringArrayTest;
    24.    
    25.     // Use this for initialization
    26.     void Start () {
    27.         Debug.Log(stringArrayTest[0][2]);
    28.     }
    29. }
    30.  
    It's a small feature and workaroundable, but It makes them easier to reference within code in my opinion.

    I don't have any useable samples because I'm working with iPhone, but if you want to use Generics you could also probably even work in a Generic serializable ArrayLayer, making it able to make 2D,3D,4D,nD arrays of any type you want with a single class.
     
    jonasblasas likes this.
  7. mattbenic

    mattbenic

    Joined:
    Nov 24, 2010
    Posts:
    38
    Out of interest, has anyone managed to get this generic version working with the inspector? Using the strictly typed version with int works a treat, as soon as I replace it with a class that is exactly the same but has it's int type replaced with a generic parameter (which is then set to int for the instance declaration) the inspector no longer displays the array.
     
  8. feyyd

    feyyd

    Joined:
    Apr 23, 2014
    Posts:
    10
    Code (csharp):
    1. public class RateRow {
    2.     [HideInInspector]
    3.     public string rate_name;
    4.     public Vector2[] rate_vector;
    5. }
    I found out you can add a public string to the row class, then hide it after it is set, and then each Element tag will be renamed to whatever you name it in inspector as well.
     
  9. sumeetkhobare

    sumeetkhobare

    Joined:
    Sep 6, 2013
    Posts:
    4
    Hey,

    I stumbled in this same issue a month ago and after solving it, I have made a solution to this, now. I have made a grid view for a 2D array.

    You can find it here:


    Its in c# though.
     
    Roman_Keivan likes this.
  10. Roman_Keivan

    Roman_Keivan

    Joined:
    May 31, 2019
    Posts:
    22
    Thanks Sir for completely explain this solution, its helped to me o_O
     
  11. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,500
    Good to show appreciation but please use the like button rather than necroing a 7 year old post.

    Thanks.
     
    Bunny83 and Roman_Keivan like this.