- Home /
Unity C# - Foreach loop - Inventory slot only changes quantity for the last child of an object
In my game, I have an inventory system. Items can get added to the inventory, and each item slot shows the quantity of an item, but I'm trying to make it that if an item is selected in the inventory (with "isOn"), and if the player uses the "Use/Equip" button, then the quantity of the item decreases by one, and the child of the item slot "text_ItemAmount" (which shows the quantity of the item) updates to show the correct quantity. However, if I have more than one items in my inventory, and I select the first item and click the "Use/Equip" button, the item decreases in quantity but it isn't shown in the game, and the "text_ItemAmount" stays to the previous quantity it was. However, If I have the very last item in the inventory selected, and I press the "Use/Equip" button, the quantity of the item decreases and the inventory slot updates it's child "text_ItemQuantity" (which shows the item's quantity in game) correctly, but this only works for the very last item, and if I try to do this for previous items, it won't set the text to the correct quantity.
Also, when the "Use/Equip" button is clicked, it says a boolean variable "use" to true.
Here is my code: (It is in the update function and will be called every frame)
foreach (Transform child in content.transform)
{
Toggle childToggle = child.GetComponent<Toggle> ();
Text ItemSlotTextAmount = child.transform.FindChild("text_ItemAmount").GetComponent<Text>();
BaseItem childBaseItemScript = child.GetComponent<BaseItem> ();
if (childToggle.isOn)
{
ItemDescriptionBox.text = childBaseItemScript.ItemDescription;
ItemIconBox.sprite = childBaseItemScript.ItemSprite;
UseEquipButton.gameObject.SetActive (true);
if (use)
{
childBaseItemScript.ItemQuantity -= 1;
itemSlotTextAmount.text = ("(x" + childBaseItemScript.ItemQuantity + ")");
use = false;
return;
}
return;
}
else if (!childToggle.isOn)
{
UseEquipButton.gameObject.SetActive(false);
ItemDescriptionBox.text = "";
ItemIconBox.sprite = emptyIcon;
}
}
Please tell me if I did not provide enough information to solve this or if something doesn't make sense. Thanks!
Do you add the click listeners to the use buttos in code or editor. If in code, how?
In the editor. Basically on the OnClick() function, It calls a function called "UseEquip" which sets the "use" variable to true. the UseEquip function is in the same script as the code above, which is called "InventoryListWindow"
This is the UseEquip function:
public void UseEquip()
{
use = true;
}
Here is how it looks in the editor:
That (second) return
at the very end of if (childToggle.isOn)
, is it there intentionally to exit the whole method so you can't interact with items after the selected one?
I'm also not sure if you can trust the order of the objects when you foreach a transform... could an unexpected order of the items cause something in combination with that return
perhaps?
I don't know if this will help, but ins$$anonymous$$d of looping through each inventory item every frame you can use pointer events to return the selected gameobject and do your logic only once when that event is called. For example, when you click the item in the inventory, a pointer event will be called and should return the selected object then you can update your descriptions, sprite, etc. Look at PointerEventData for more info :)
i see you have put much effort into your question, but this is almost too broud to follow and could be many problems. To narrow a problem I like to use the print function in the councel. I temporarily use print before every relevant line to eli$$anonymous$$ate possibility's of a wrong input/expectation until you see what line the unexpected results are co$$anonymous$$g from. it's a good process to find exactly where the problem is.
Answer by john2165 · Jun 18, 2017 at 04:31 AM
Thanks for the reply everyone, but I fixed the problem yesteday. turns out one of my variables (line 14) was spelt with a lowercase "i" instead of an uppercase "I".