1
\$\begingroup\$

I have a 2d array for 'Slots' in my inventory screen (slot width: 150px; total slots is based on width and height of inventory panel currently at 1500x600). The slot holds a reference to the pickupObjects that the player has picked up and added to the inventory (these items have been stored in a list).

So I try to make a method which fills the slots using the List of pickupItems. But the problem is that when I iterate through the inventory it will reach a number higher than the width of the first row of slots. I feel like the answer can be simple, but I just can't seem to figure out how to iterate through them and place it into the 2d array. I've solved this very issue in the past but can't remember how I did it.

Here's the code I have for creating the grid of slots, and then the method for putting the inventory in there (even though this method is pretty much empty right now as I am completely out of ideas):

Any help would be massively appreciated. Thanks

void CreateSlotLayout()
{
    panel_rt = GetComponent<RectTransform>();
    panelWidth = panel_rt.rect.width;
    panelHeight = panel_rt.rect.height;
    slotCount_x = (int)(panelWidth / slotWidth);
    slotCount_y = (int)(panelHeight / slotHeight);
    slots = new Slot[slotCount_x, slotCount_y];

    for (int y = 0; y < slotCount_y; y++)
    {
        for (int x = 0; x < slotCount_x; x++)
        {
            Slot slot = Instantiate(slotPrefab);
            slot.transform.SetParent(transform);
            slot.GetComponent<RectTransform>().anchoredPosition = new Vector2(x * slotWidth, -y * slotHeight);
            slots[x, y] = slot;
        }
    }
}

public void FillSlotsWithInventory(Player_Inventory playerInventory)
{
    for (int i = 0; i < playerInventory.GetPickupsList().Count; i++)
    {
          //something like....
          //slots[i?,i?].FillSlot(playerInventory.GetPickupsList[i];
    }
}
\$\endgroup\$

1 Answer 1

2
\$\begingroup\$

The typical way to do this is to make use of the fact that integer division truncates (the row, y), in combination with modulus operator to get the remainder (the column, x). In code, that looks like this:

public void FillSlotsWithInventory(Player_Inventory playerInventory)
{
    int pickups_count = playerInventory.GetPickupsList().Count;
    for (int i = 0; i < pickups_count; i++)
    {
        int x = i % slotCount_x;
        int y = i / slotCount_x;
        slots[x, y].FillSlot(playerInventory.GetPickupsList[i]);
    }
}

For a 3x3 inventory grid and 9 pickups, the data looks like this:

i => [x,y]
-----------
0 => [0,0]
1 => [1,0]
2 => [2,0]
3 => [0,1]
4 => [1,1]
5 => [2,1]
6 => [0,2]
7 => [1,2]
8 => [2,2]

If you want to do the opposite calculation ([x,y] => i), it's also quite straightforward:

int i = (y * slotCount_x) + x;

For which the data (predictably so) looks like this:

[0,0] => 0
[1,0] => 1
[2,0] => 2
[0,1] => 3
[1,1] => 4
[2,1] => 5
[0,2] => 6
[1,2] => 7
[2,2] => 8

Side note: Generally 2D arrays are indexed as [y, x] rather than [x, y] because it keeps the data in order in memory. This is not terribly important if you're doing random access into the array, but if you're iterating over it often it may help with performance. As always, profile your code before deciding that this it the most valuable thing to spend your time optimizing.

\$\endgroup\$
1
  • \$\begingroup\$ thanks for the help with this mate. I had a feeling the modulus thing would be the answer but had no idea where to start with it. Also very interesting about the y,x thing as I noticed I had to iterate through y first so that I could make the slots in the order I desired (ie. from left to right and top to bottom same way we write a page of english for example). I am going to look through your answer several times until i fully understand it (:D) thanks again \$\endgroup\$ Jun 7, 2019 at 1:11

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .