Hello! So I am making an inventory system and am having an issue with the pickup system. So I have a “Drops” folder in Workspace that hold all the dropped items. And then I use this code to loop through them and detect when they are clicked on to pick up:
for i, v in pairs(Drops:GetChildren()) do
print("Test")
v:FindFirstChildWhichIsA("ClickDetector", true).MouseClick:Connect(function(plr)
local Inventory = ServerStore.Inventory:FindFirstChild(plr.Name) --Gets the player's inventory.
local Items = Inventory:WaitForChild("Items") --Gets the folder where the items that the player picks up are stored.
local MaxItems = Items:WaitForChild("MaxItems") -- this and the line below are for max capacity stuff.
local CurrentWeight = Items:WaitForChild("CurrentWeight")
print(plr.Name.." Attempted to pickup: "..v.Name)
if CurrentWeight.Value + v:FindFirstChild("Weight").Value <= MaxItems.Value then
print(plr.Name.." Has enough space and has picked up: "..v.Name)
if not Items:FindFirstChild(v.Name) then
game.ReplicatedStorage.Remotes.InventoryRemotes.UpdateInventory:FireClient(plr, "AddSlot", v)
else
game.ReplicatedStorage.Remotes.InventoryRemotes.UpdateInventory:FireClient(plr, "UpdateSlot", v)
end
v.Parent = Items
CurrentWeight.Value += v:FindFirstChild("Weight").Value
print("Player Space: "..CurrentWeight.Value.."/"..MaxItems.Value)
else
print(plr.Name.." Does not have enough space to pick up: "..v.Name)
print("Player Space: "..CurrentWeight.Value.."/"..MaxItems.Value)
end
end)
end
But I’ve run into the issue that I am able to pickup items that I had put into the drops folder manually in edit mode, but once new drops are created it doesn’t register them and won’t pick them up, but still allows you to pickup the ones that existed already
I think it may be because it loops once and only detects those items but not the new ones. So I thought that maybe I could put it in a function and connect it to a DecendantAdded function to refresh it.
Which partially worked but it would end up causing it to register the items, that existed before it was called again, twice (or more if it was called multiple times). So my question is how would I refresh the loop and make it not register items multiple times?
Sorry if this is confusing. I don’t know any other way of explaining it.
You basically presented the solution precisely. You need another event definition to handle initializing new drops so they can be interacted with.
local function onDropAdded(v)
v:FindFirstChildWhichIsA("ClickDetector", true).MouseClick:Connect(function(plr)
local Inventory = ServerStore.Inventory:FindFirstChild(plr.Name) --Gets the player's inventory.
local Items = Inventory:WaitForChild("Items") --Gets the folder where the items that the player picks up are stored.
local MaxItems = Items:WaitForChild("MaxItems") -- this and the line below are for max capacity stuff.
local CurrentWeight = Items:WaitForChild("CurrentWeight")
print(plr.Name.." Attempted to pickup: "..v.Name)
if CurrentWeight.Value + v:FindFirstChild("Weight").Value <= MaxItems.Value then
print(plr.Name.." Has enough space and has picked up: "..v.Name)
if not Items:FindFirstChild(v.Name) then
game.ReplicatedStorage.Remotes.InventoryRemotes.UpdateInventory:FireClient(plr, "AddSlot", v)
else
game.ReplicatedStorage.Remotes.InventoryRemotes.UpdateInventory:FireClient(plr, "UpdateSlot", v)
end
v.Parent = Items
CurrentWeight.Value += v:FindFirstChild("Weight").Value
print("Player Space: "..CurrentWeight.Value.."/"..MaxItems.Value)
else
print(plr.Name.." Does not have enough space to pick up: "..v.Name)
print("Player Space: "..CurrentWeight.Value.."/"..MaxItems.Value)
end
end)
end
--//account for existing drops
for _, drop in Drops:GetChildren() do onDropAdded(drop) end
--//initialize new drops
Drops.ChildAdded:Connect(onDropAdded)
That did allow me to pick up new items but it causes duplicate registering. Here is a video showing what is happening: robloxapp-20221109-1953131.wmv (5.4 MB)
(Sorry for it not being mp4. Always have issues when uploading those)
I’m not exactly sure why it’s causing that to happen, but to account for that you could use a dictionary to store each pickup and determine if the object has already been stored:
--//top of script
local pickupObjects = {}
--//At the top of the onDropAdded function
if pickupObjects[v] then return end
pickupObjects[v] = true