Search Unity

Problem grabbing an empty gameobject?

Discussion in 'Scripting' started by Flynn_Prime, Oct 21, 2017.

  1. Flynn_Prime

    Flynn_Prime

    Joined:
    Apr 26, 2017
    Posts:
    387
    Afternoon,
    I'm struggling with this, and not sure how it is not working as the code seems sound. The following is the code for part of my inventory UI. I have a loadout system (3 different sets of gear system) and when I change loadout, I clear and rebuild my inventory UI to remove items that are equipped in the current loadout, and to add all other items. When an item is added to the inventory UI it looks for the next empty slot and instantiate an image. This all works fine, except for when I change to another loadout, sometimes my item in the inventory skips a slot or two even though there is nothing in the one before it. The code to grab the next empty slot is simple, and I know it works as I use it also when unequipping items, which works correctly.

    This is the part that doesn't seem to always work properly. Any help would be very much appreciated!

    Code (CSharp):
    1. private void CreateSlots ()
    2.     {
    3.         for (int i = 0; i < inventorySize; i++)
    4.         {
    5.             var _slot = Instantiate (slot);
    6.             _slot.transform.SetParent (slotContainer.transform, false);
    7.         }
    8.     }
    9.  
    10.     public void ClearUI ()
    11.     {
    12.         foreach (Transform t in slotContainer.transform)
    13.         {
    14.             if (t.childCount != 0)
    15.             {
    16.                 Destroy (t.GetChild (0).gameObject);
    17.             }
    18.         }
    19.     }
    20.  
    21.     public void RebuildUI (string loadName)
    22.     {
    23.         bool isEquipped = false;
    24.         foreach (Item i in inventory)
    25.         {
    26.             Equipment e = (Equipment)i;
    27.             switch (loadName)
    28.             {
    29.             case "Load_One":
    30.                 isEquipped = e.isEquipped_Load1;
    31.                 break;
    32.             case "Load_Two":
    33.                 isEquipped = e.isEquipped_Load2;
    34.                 break;
    35.             case "Load_Three":
    36.                 isEquipped = e.isEquipped_Load3;
    37.                 break;
    38.             default:
    39.                 break;
    40.             }
    41.             if (isEquipped != true)
    42.             {
    43.                 AddItemToInventoryUI (i);
    44.             }
    45.         }
    46.     }
    47.  
    48.     //Adds to UI (from Loadout and Store)
    49.     public void AddItemToInventoryUI (Item i)
    50.     {
    51.         Transform emptySlot = GrabNextEmptySlot ();
    52.         var icon = Instantiate (slotImage);
    53.         icon.name = i.itemSlug;
    54.         icon.transform.SetParent (emptySlot, false);
    55.         icon.GetComponent<Image> ().sprite = i.itemIcon;
    56.     }
    57.  
    58.     public Transform GrabNextEmptySlot ()
    59.     {
    60.         foreach (Transform t in slotContainer.transform)
    61.         {
    62.             if (t.childCount == 0)
    63.             {
    64.                 return t;
    65.             }
    66.         }
    67.         return null;
    68.     }
     

    Attached Files:

    Last edited: Oct 21, 2017
  2. Flynn_Prime

    Flynn_Prime

    Joined:
    Apr 26, 2017
    Posts:
    387
  3. Brathnann

    Brathnann

    Joined:
    Aug 12, 2014
    Posts:
    7,188
    Destroying objects doesn't happen till the end of the frame, so it's possible the object isn't destroyed yet when you go to repopulate.

    If you can't use object pooling, I think you can simply change the parent of anything you want to destroy right before you call destroy on it, the the slot will not have a child anymore.
     
  4. Flynn_Prime

    Flynn_Prime

    Joined:
    Apr 26, 2017
    Posts:
    387
    Wasn't aware of that! Thank you