Inventory System doesn't update until a new item is added

Hey, I’m making a simple inventory system.

Whenever I collect a new item, it doesn’t clone the template button as it should; but instead it updates when a new item is added.


I’ve been trying to fix it for half an hour!

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")

local player = Players.LocalPlayer
local inventory = player:WaitForChild("Inventory")

local events = ReplicatedStorage:WaitForChild("Events")
local hats = ReplicatedStorage:WaitForChild("Hats")

local inventoryGui = script.Parent
local mainFrame = inventoryGui:WaitForChild("MainFrame")
local itemFrame = mainFrame:WaitForChild("ItemFrame")
local inspectFrame = mainFrame:WaitForChild("InspectFrame")

local sellButton = inspectFrame:WaitForChild("SellButton")
local equipButton = inspectFrame:WaitForChild("EquipButton")

local itemNameLabel = inspectFrame:WaitForChild("ItemNameLabel")
local itemValueLabel = inspectFrame:WaitForChild("ItemValueLabel")

local template = script:WaitForChild("Template")

local function UpdateInventory ()
	for i, v in ipairs(itemFrame:GetChildren()) do
		if v:IsA("TextButton") then 
			v:Destroy() 
		end
	end
	
	for i, v in ipairs(inventory:GetChildren()) do
		if not (v.Value > 0) then return end
		
		local templateClone = template:Clone()
		templateClone.Text = v.Name
		templateClone.ItemAmountLabel.Text = v.Value
		templateClone.Parent = itemFrame
		
		templateClone.MouseButton1Click:Connect(function()
			itemNameLabel.Text = v.Name
			itemValueLabel.Text = "R$ "..hats:FindFirstChild(v.Name):GetAttribute("Value")
		end)
	end
end

for i, v in ipairs(inventory:GetChildren()) do
	v:GetPropertyChangedSignal("Value"):Connect(function()
		UpdateInventory()
	end)
end

Try printing something whenever the function is called. Does it run when you want it to?

I think a part of the problem may be your method of storing items. Is the number of children inside the inventory static when this code is active, or no?

Not even sure how to put this into words but this is what happens.

It printed once when I picked up the chill cap.

Your problem most likely lies within this block of code:

for i, v in ipairs(inventory:GetChildren()) do
	v:GetPropertyChangedSignal("Value"):Connect(function()
		UpdateInventory()
	end)
end

I would assume it has something to do with how children/descendants are added to the inventory, so make sure that the script is always aware of every item in the inventory, from the moment a new one is added. You can do this by using functions like Instance.ChildAdded and Instance.DescendantAdded. (assuming each new item is added as a child/descendant of the inventory)

The items are added via a for loop.

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")

local hats = ReplicatedStorage.Hats

local function playerAdded(player)
	local leaderstatsClone = script.leaderstats:Clone()
	leaderstatsClone.Parent = player
	
	local inventoryClone = script.Inventory:Clone()
	inventoryClone.Parent = player
	
	for _, hat in ipairs(hats:GetChildren()) do
		local hatValue = Instance.new("IntValue")
		hatValue.Name = hat.Name
		hatValue.Value = 0
		hatValue.Parent = inventoryClone
	end
end

Players.PlayerAdded:Connect(playerAdded)

for _, player in ipairs(Players:GetPlayers()) do
	playerAdded(player)
end

Sidenote: This probably isn’t the most performant way of doing it but it’s how I see it everywhere.

Maybe try doing UpdateInventory() at the line before the ipairs loop to update it before the value changes, or higher up in the script to update sooner.

What is this for…?

for _, player in ipairs(Players:GetPlayers()) do
	playerAdded(player)
end

I remember seeing it was good practice to do that, although my memory probably decieved me.

I don’t think that for loop will be doing any good for the script, as it will run just once and only when the first player joins the server… which already has a function connected to that event.

Also, make sure that your client-side script waits for the server to finish copying everything the inventory and leaderstats over to the player instance before running. This may be part of the reason your script isn’t working.

Turns it out it was just the check!

When I turned it from

if not (v.Value > 0) then return end

To

if (v.Value > 0) then

It worked flawlessly. Thanks guys!

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.