I want to make my own inventory, but unfortunately, I’m a beginner programmer. I started making the inventory, but when I tried to drop an item, I encountered bugs and errors. Please help me understand the error and, if possible, optimize it.)
ToggleInventoryUI
local UIS = game:GetService("UserInputService")
local screenGui = script.Parent
local player = game:GetService("Players").LocalPlayer
local backpack = player:FindFirstChild("Backpack")
local character = player.Character
UIS.MouseBehavior = Enum.MouseBehavior.LockCenter
local mouseBehavior = Enum.MouseBehavior.LockCenter
UIS.InputBegan:Connect(function(input, gameProcessed)
if gameProcessed then return end
if input.KeyCode == Enum.KeyCode.B then
local newState = not screenGui.Enabled
screenGui.Enabled = newState
if newState then
mouseBehavior = Enum.MouseBehavior.Default
UIS.MouseBehavior = Enum.MouseBehavior.Default
else
mouseBehavior = Enum.MouseBehavior.LockCenter
UIS.MouseBehavior = Enum.MouseBehavior.LockCenter
end
end
end)
player.Backpack.ChildAdded:Connect(function(a)
print(a)
local character = player.Character
local mainLocalScript = character:FindFirstChild("MainLocalScript")
local amountInBP = mainLocalScript:FindFirstChild("AmountInBP")
amountInBP.Value += 1
end)
local Frame = screenGui.Frame
for i,v in pairs(Frame:GetChildren()) do
v.MouseButton1Click:Connect(function()
if v:WaitForChild("Item").Value ~= "" then
print("Hold")
local Item = backpack:GetChildren()[i]
end
end)
v.MouseButton2Click:Connect(function()
if v:WaitForChild("Item").Value ~= "" then
print("Throw")
local Item = backpack:GetChildren()[i]
v.Image = ""
v:WaitForChild("Item").Value = ""
Item.Parent = workspace
Item:FindFirstChild("Base").Anchored = false
Item:FindFirstChild("Base").AssemblyLinearVelocity = Vector3.new(0, -10, 0)
end
end)
end
Script(Part)
local Tool = script.Parent
local Part = Tool.Base
local ProximityPromt = Part.ProximityPrompt
local RS = game:GetService("ReplicatedStorage")
local InventoryFullNotification = RS.Remotes:WaitForChild("InventoryFullNotification")
local Maximum = 8
ProximityPromt.PromptButtonHoldBegan:Connect(function(player)
local character = player.Character
local mainLocalScript = character:FindFirstChild("MainLocalScript")
local amountInBP = mainLocalScript:FindFirstChild("AmountInBP")
if amountInBP and amountInBP.Value >= Maximum then
ProximityPromt.Enabled = false
InventoryFullNotification:FireClient(player, Maximum)
task.wait(0.1)
ProximityPromt.Enabled = true
return
end
end)
ProximityPromt.Triggered:Connect(function(player)
local GUI = player.PlayerGui:WaitForChild("InventoryGui")
print(GUI.Parent.Parent.Name)
local Frame = GUI.Frame
for i = 1,8 do
local Slot = Frame:WaitForChild("Slot" .. i)
if Slot:WaitForChild("Item").Value == "" then
Slot:WaitForChild("Item").Value = Tool.Name
print(Slot.Name)
Slot.Image = RS.FramesForInventory:WaitForChild(Tool.Name).Texture
break
end
end
Tool.Parent = player.Backpack
end)
hey so basically the problem is super simple, you’re using the wrong way to find the tool when dropping it
the issue is here i think:
local Item = backpack:GetChildren()[i]
that i is just the slot number (1-8) from the frame loop, but the backpack might have tools in a different order. so ur grabbing random tools or nothing at all
quick fix:
change it to find by name instead:
v.MouseButton2Click:Connect(function()
if v:WaitForChild("Item").Value ~= "" then
local Item = backpack:FindFirstChild(v:WaitForChild("Item").Value)
if Item then
v.Image = ""
v:WaitForChild("Item").Value = ""
Item.Parent = workspace
local handle = Item:FindFirstChild("Base")
if handle then
handle.Anchored = false
handle.CFrame = character.HumanoidRootPart.CFrame * CFrame.new(0, 2, -3)
task.wait()
handle.AssemblyLinearVelocity = Vector3.new(0, 5, 0)
end
end
end
end)
Please try this solution, if it doesn’t work feel free to tell me:)
Okay. Look: when I drop an item, it drops (even though it’s weird), but the slot doesn’t empty, and then I get this:
Players.GrOgRo401.PlayerGui.InventoryGui.ToggleInventoryUI:57: attempt to index nil with ‘Parent’
Item is nil which means the tool isnt in the backpack when ur trying to drop it the problem: the tool might still be in the character (equipped) not in backpack, OR it already got removed somehow
v.MouseButton2Click:Connect(function()
if v:WaitForChild("Item").Value ~= "" then
-- Check both backpack AND character
local Item = backpack:FindFirstChild(v:WaitForChild("Item").Value) or character:FindFirstChild(v:WaitForChild("Item").Value)
if Item then
-- Clear slot FIRST
v.Image = ""
v:WaitForChild("Item").Value = ""
-- Update the counter
local mainLocalScript = character:FindFirstChild("MainLocalScript")
if mainLocalScript then
local amountInBP = mainLocalScript:FindFirstChild("AmountInBP")
if amountInBP then
amountInBP.Value -= 1
end
end
-- Now drop it
Item.Parent = workspace
local handle = Item:FindFirstChild("Base")
if handle then
handle.Anchored = false
handle.CFrame = character.HumanoidRootPart.CFrame * CFrame.new(0, 2, -3)
task.wait()
handle.AssemblyLinearVelocity = Vector3.new(0, 5, 0)
end
end
end
end)
the or character:FindFirstChild() part checks both places for the tool. also added the counter decrease so the inventory actually updates properly
The problem is that the slot the item was in isn’t freed up, and when I pick up the item, it moves to the next slot. Therefore, when I discard it, the program searches the next slot, not the one the item is in.
Something like: I discarded an item from the first slot, I pick it up, and it moves to the second slot (there’s an error here; slot 1 isn’t free for some reason). When I click discard, the program searches for slot 2, which is empty, because the item was picked up in slot 1.
the real problem: backpack children order ≠ slot order. when u pick up items they dont go in order 1-8 in the backpack solution: store actual tool references in a table that matches ur slots
add this at the top of ur script:
local slotTools = {} -- tracks which tool is in which slot
then when picking up (modify the proximity prompt part):
for i = 1,8 do
local Slot = Frame:WaitForChild("Slot" .. i)
if Slot:WaitForChild("Item").Value == "" then
Slot:WaitForChild("Item").Value = Tool.Name
Slot.Image = RS.FramesForInventory:WaitForChild(Tool.Name).Texture
-- Store the tool reference
game:GetService("ReplicatedStorage").Remotes.StoreSlotTool:FireClient(player, i, Tool)
break
end
end
then dropping becomes:
v.MouseButton2Click:Connect(function()
local slotNum = tonumber(v.Name:match("%d+"))
local Item = slotTools[slotNum]
if Item then
slotTools[slotNum] = nil
v.Image = ""
v:WaitForChild("Item").Value = ""
-- rest of drop code
Item.Parent = workspace
-- etc
end
end)
Hooraaaaaaaaay
In short, the item was dropped only in the client and nothing was reported to the server => the program still thought that I had an item in slot 1.
If anyone encounters a similar error, here is the answer: you need to tell the server that the item has been discarded.