Issues with the assigning of dictionary keys

I’ve got an issue with assigning keys to new dictionary positions using a loop. this is my code:

public void GenerateMapTiles()
    {
        for (int x = 0; x < 10; x++)
        {   for (int z = 0; z < 10; z++)
            {   TileTypes2 tt = tileType[tile[x, z]];
                GameObject go = Instantiate(tt.tileVisualPrefab, new Vector3(x, 0, z), Quaternion.identity);
                OnTile ot = go.GetComponent<OnTile>();
                ot.tileX = x;
                ot.tileZ = z;
                trueTiles.Add(new int[x, z], ot);
                //Debug.Log(trueTiles.Count);
            }
        }
    }

I also have the Dictionary created like this:

public Dictionary<int[,], OnTile> trueTiles = new Dictionary<int[,], OnTile>();

But when I call for an ‘OnTile’ script using a key such as [1,1] it just throws an error and says the given key was not in the dictionary.

public void TEST()
    {   
        for(int x = 0; x < 10; x++)
        {
            for (int z = 0; z< 10; z++)
            {
                Debug.Log(trueTiles.ContainsKey(new int[x, z]));
            }
        }

    }

but when I called that function, it just returns false, for every single item.
and, when I do trueTiles.keys; it returns a list of keys but in the console it shows each key as ‘Int32[,]’, so I’ve come to the conclusion that the loop i have is not setting the keys for some reason.
I’m new to Coding and I don’t understand what I’m doing wrong here and I would appreciate it if somebody could tell me how to fix this. or if somebody could tell me a better way to do this?

//My goal with this script is to create a way to access an ‘OnTile’ script by using its respective position in the map in an x,z format like so:

if( trueTiles[new int[5, 4]].isOccupied == true)
        {
            //do something
        }

When you use something like int[5,4], you are declaring an array of integers, essentially a big “matrix”, in this case it’s a matrix with 5 rows and 4 columns for a total of 20 different integers. By the way you are trying to use it, I think you want to use coordinates, but are just using the wrong tools for that.
Arrays are reference types. When you use them as keys to a dictionary, you must pass in the exact same array reference to get the corresponding key. Even if you create a new array of the same size with the exact same elements, the array references are still not the same, so they will not work as the same key. You can think of the arrays like bags. Just because you have two bags that are the same size and have the same stuff in them, does not mean they are the same bag.
The first step you should take here is to not use arrays as the key for the dictionary. Although C# will allow you to do that, I have never seen this done on purpose (+10 year professional experience). Instead, you could use tuples: Tuple types - C# reference | Microsoft Learn
The declaration of the dictionary would look like this:

Dictionary<(int,int), OnTile>  trueTiles = new Dictionary<(int,int), OnTile>();

Note that the key is of type (int,int), which is a tuple with two ints in it.
You access the dictionary like this:

trueTiles[(x,y)] = someOnTileReference;
if( trueTiles[(5,4)].isOccupied == true)
{
            //do something
}
1 Like

Switch from using int[,] which is a two dimensional array and makes absolutely zero sense as a key in this dictionary to using Vector2Int and it will work fine.

e.g. everywhere you have new int[x, z] change that to new Vector2Int(x, z)

The reason this isn’t working is because you’re creating brand new 2D arrays every single time that are completely unrelated to each other. And since arrays are reference types, two arrays with the same dimensions are not the same object.

Edit:
@Trafulgoth_1 and I are suggesting basically the same thing. Vector2Int happens to be a named struct that Unity created that is more or less equivalent to the (int, int) tuple.

1 Like

Thank you, I applied your suggested changes and it works like a charm. :slight_smile: you were correct, I misunderstood what int[,] was.