I have a problem with my Backpack (Script)

Hello I have a problem with my script. When I Clone an object in my Backpack it is not displayed while objects in StarterPack are displayed.

I made a video to explain better.

The script is located in StarterCharacterScripts and it is a local script.
Here is the script in question.

local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local UserInputService = game:GetService("UserInputService")
local Player = Players.LocalPlayer

local RunService = game:GetService("RunService")

for i, item in ipairs(Player.Backpack:GetChildren()) do
	local cloneItemFrame = ReplicatedStorage.Item:Clone()
	cloneItemFrame.TextLabel.Text = tostring(i)
	cloneItemFrame.Tool.Value = item.Name
	cloneItemFrame.ImageLabel.Image = item.TextureId
	cloneItemFrame.Parent = Player.PlayerGui.Backpack.Frame;
	
	cloneItemFrame.ImageButton.MouseButton1Down:Connect(function() 
		local tool = Player.Backpack:FindFirstChild(cloneItemFrame.Tool.Value)
		local character = Player.Character or Player.Character:WaitForChild()
		local humanoid = character.Humanoid;
		
		local strokeFound = cloneItemFrame:FindFirstChild("UIStroke")
		
		if strokeFound then
			strokeFound:Destroy();
			humanoid:UnequipTools() 
			return;
		end
		
		for i, frame in ipairs(Player.PlayerGui.Backpack.Frame:GetChildren()) do
			for i, item in ipairs(frame:GetChildren()) do
				if item.Name == "UIStroke" then
					item:Destroy();
				end
			end
		end

		local stroke = Instance.new("UIStroke")
		stroke.Color = Color3.fromRGB(255, 255, 255);
		stroke.Parent = cloneItemFrame;
		stroke.Thickness = 2.1

		task.wait(0.10)
		humanoid:EquipTool(tool)
	end)
end

local KeyCodes = {
	[49] = 1,
	[50] = 2,
	[51] = 3,
	[52] = 4,
	[53] = 5,
	[54] = 6,
	[55] = 7
}

UserInputService.InputBegan:Connect(function(input: InputObject) 
	for i, item in ipairs(Player.PlayerGui.Backpack.Frame:GetChildren()) do
		if item:IsA("Frame") then
			for i, child in ipairs(item:GetChildren()) do
				if child:IsA("TextLabel") then
					if KeyCodes[input.KeyCode.Value] == tonumber(child.Text) then
						local tool = Player.Backpack:FindFirstChild(item.Tool.Value)
						local character = Player.Character or Player.Character:WaitForChild()
						local humanoid = character.Humanoid;

						local strokeFound = item:FindFirstChild("UIStroke")

						if strokeFound then
							strokeFound:Destroy();
							humanoid:UnequipTools() 
							return;
						end

						for i, frame in ipairs(Player.PlayerGui.Backpack.Frame:GetChildren()) do
							for i, item in ipairs(frame:GetChildren()) do
								if item.Name == "UIStroke" then
									item:Destroy();
								end
							end
						end

						local stroke = Instance.new("UIStroke")
						stroke.Color = Color3.fromRGB(255, 255, 255);
						stroke.Parent = item;
						stroke.Thickness = 2.1

						task.wait(0.10)
						humanoid:EquipTool(tool)
					end
				end
			end
		end
	end 
end)

Thank you for those who will help me.

5 Likes

I assume that the first for loop is responsible for making the hotbar icons appear.
However, this only runs once when the script loads, so when you have the chicken added to your backpack, that icon doesnt appear.

Or am I mistaken, and the second for loop is meant to make that icon appear?

If so, you could do something along the lines of:

  • Have a function that is able to add a hotbar icon, given a tool as a parameter.
  • Then use “childAdded” to detect whenever a new tool is added to the players backpack, and when it is added , call that function I said earlier.
4 Likes

I will admit to you that with my skills I will not be able to script this.
Sorry

4 Likes
Player.Backpack.ChildAdded:Connect(function(child)
    if not (child:IsA("Tool")) then return end

    -- this code was copied from your first for loop 
    -- probably needs to be modified
    local cloneItemFrame = ReplicatedStorage.Item:Clone()
    cloneItemFrame.TextLabel.Text = tostring(i)
    cloneItemFrame.Tool.Value = item.Name
    cloneItemFrame.ImageLabel.Image = item.TextureId
    cloneItemFrame.Parent = Player.PlayerGui.Backpack.Frame;

    -- and so on (connect up mouse button down function etc)
end)
2 Likes

I can’t understand why it does that

3 Likes

Oh thats my mistake.

Whenever you equip a tool, if moves from your backpack (which is childed to the player object) to your character model. Then when you unequip said tool, it moves back to your backpack.
So the child added event is triggering many times - which is unwanted.

– Local script

local displayedItems = {}

Player.Backpack.ChildAdded:Connect(function(child)
    if not (child:IsA("Tool")) then return end
    if table.find(displayedItems, child) then return end

    table.insert(displayedItems, child)
    -- rest of the code to display the item (cloneItemFrame, etc)
end)

3 Likes

There is still the same problem.

3 Likes

My bad.

local displayedItems = {}

Player.Backpack.ChildAdded:Connect(function(child)
    if not (child:IsA("Tool")) then return end
    if table.find(displayedItems, child.Name) then return end

    table.insert(displayedItems, child.Name)
    -- rest of the code to display the item (cloneItemFrame, etc)
end)
1 Like

it’s the same problem again as if not deleting the Frames from before

3 Likes

Could you post your full script please?

3 Likes
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local UserInputService = game:GetService("UserInputService")
local Player = Players.LocalPlayer

local RunService = game:GetService("RunService")


for i, item in ipairs(Player.Backpack:GetChildren()) do
	local cloneItemFrame = ReplicatedStorage.Item:Clone()
	cloneItemFrame.TextLabel.Text = tostring(i)
	cloneItemFrame.Tool.Value = item.Name
	cloneItemFrame.ImageLabel.Image = item.TextureId
	cloneItemFrame.Parent = Player.PlayerGui.Backpack.Frame;
	
	local displayedItems = {}
	
	Player.Backpack.ChildAdded:Connect(function(child)
		if not (child:IsA("Tool")) then return end
		if table.find(displayedItems, child.Name) then return end
		
		table.insert(displayedItems, child.Name)
		
		local cloneItemFrame = ReplicatedStorage.Item:Clone()
		cloneItemFrame.TextLabel.Text = tostring(i)
		cloneItemFrame.Tool.Value = item.Name
		cloneItemFrame.ImageLabel.Image = item.TextureId
		cloneItemFrame.Parent = Player.PlayerGui.Backpack.Frame;

		cloneItemFrame.ImageButton.MouseButton1Down:Connect(function() 
			local tool = Player.Backpack:FindFirstChild(cloneItemFrame.Tool.Value)
			local character = Player.Character or Player.Character:WaitForChild()
			local humanoid = character.Humanoid;

			local strokeFound = cloneItemFrame:FindFirstChild("UIStroke")

			if strokeFound then
				strokeFound:Destroy();
				humanoid:UnequipTools() 
				return;
			end

			for i, frame in ipairs(Player.PlayerGui.Backpack.Frame:GetChildren()) do
				for i, item in ipairs(frame:GetChildren()) do
					if item.Name == "UIStroke" then
						item:Destroy();
					end
				end
			end

			local stroke = Instance.new("UIStroke")
			stroke.Color = Color3.fromRGB(255, 255, 255);
			stroke.Parent = cloneItemFrame;
			stroke.Thickness = 2.1

			task.wait(0.10)
			humanoid:EquipTool(tool)
		end)
	end)
end


local KeyCodes = {
	[49] = 1,
	[50] = 2,
	[51] = 3,
	[52] = 4,
	[53] = 5,
	[54] = 6,
	[55] = 7
}

UserInputService.InputBegan:Connect(function(input: InputObject) 
	for i, item in ipairs(Player.PlayerGui.Backpack.Frame:GetChildren()) do
		if item:IsA("Frame") then
			for i, child in ipairs(item:GetChildren()) do
				if child:IsA("TextLabel") then
					if KeyCodes[input.KeyCode.Value] == tonumber(child.Text) then
						local tool = Player.Backpack:FindFirstChild(item.Tool.Value)
						local character = Player.Character or Player.Character:WaitForChild()
						local humanoid = character.Humanoid;

						local strokeFound = item:FindFirstChild("UIStroke")

						if strokeFound then
							strokeFound:Destroy();
							humanoid:UnequipTools() 
							return;
						end

						for i, frame in ipairs(Player.PlayerGui.Backpack.Frame:GetChildren()) do
							for i, item in ipairs(frame:GetChildren()) do
								if item.Name == "UIStroke" then
									item:Destroy();
								end
							end
						end

						local stroke = Instance.new("UIStroke")
						stroke.Color = Color3.fromRGB(255, 255, 255);
						stroke.Parent = item;
						stroke.Thickness = 2.1

						task.wait(0.10)
						humanoid:EquipTool(tool)
					end
				end
			end
		end
	end 
end)
3 Likes

Whats this section for?

UserInputService.InputBegan:Connect(function(input: InputObject) 
	for i, item in ipairs(Player.PlayerGui.Backpack.Frame:GetChildren()) do
		if item:IsA("Frame") then
			for i, child in ipairs(item:GetChildren()) do
				if child:IsA("TextLabel") then
					if KeyCodes[input.KeyCode.Value] == tonumber(child.Text) then
						local tool = Player.Backpack:FindFirstChild(item.Tool.Value)
						local character = Player.Character or Player.Character:WaitForChild()
						local humanoid = character.Humanoid;

						local strokeFound = item:FindFirstChild("UIStroke")

						if strokeFound then
							strokeFound:Destroy();
							humanoid:UnequipTools() 
							return;
						end

						for i, frame in ipairs(Player.PlayerGui.Backpack.Frame:GetChildren()) do
							for i, item in ipairs(frame:GetChildren()) do
								if item.Name == "UIStroke" then
									item:Destroy();
								end
							end
						end

						local stroke = Instance.new("UIStroke")
						stroke.Color = Color3.fromRGB(255, 255, 255);
						stroke.Parent = item;
						stroke.Thickness = 2.1

						task.wait(0.10)
						humanoid:EquipTool(tool)
					end
				end
			end
		end
	end 
end)
3 Likes

This is so that when you press a key on the keyboard it equips the object.

3 Likes

Oh ok, I see the issue. Are you familiar with functions?

edit: as in

function test(param1, param2) 
  -- process
  return x
end

test("test", 5)
3 Likes

can you explain to me what the X is?

3 Likes

That was just a placeholder, technically it would error because it’s undefined, a better example:

function addTwoNumbers(number1, number2)
   local sum = number1 + number2
   return sum
end

addTwoNumbers(5, 3) --> 8

Only reason I bring this up is because I think your code would benefit from it - specifically putting all the code related to cloning the item frame into its own function.

2 Likes

Replace your original for loop with this

function createItemFrame(text)
  	local cloneItemFrame = ReplicatedStorage.Item:Clone()
	cloneItemFrame.TextLabel.Text = text
	cloneItemFrame.Tool.Value = item.Name
	cloneItemFrame.ImageLabel.Image = item.TextureId
	cloneItemFrame.Parent = Player.PlayerGui.Backpack.Frame;
	
	cloneItemFrame.ImageButton.MouseButton1Down:Connect(function() 
		local tool = Player.Backpack:FindFirstChild(cloneItemFrame.Tool.Value)
		local character = Player.Character or Player.Character:WaitForChild()
		local humanoid = character.Humanoid;
		
		local strokeFound = cloneItemFrame:FindFirstChild("UIStroke")
		
		if strokeFound then
			strokeFound:Destroy();
			humanoid:UnequipTools() 
			return;
		end
		
		for i, frame in ipairs(Player.PlayerGui.Backpack.Frame:GetChildren()) do
			for i, item in ipairs(frame:GetChildren()) do
				if item.Name == "UIStroke" then
					item:Destroy();
				end
			end
		end

		local stroke = Instance.new("UIStroke")
		stroke.Color = Color3.fromRGB(255, 255, 255);
		stroke.Parent = cloneItemFrame;
		stroke.Thickness = 2.1

		task.wait(0.10)
		humanoid:EquipTool(tool)
	end)
end

-- Create item frames for the tools which are replicated from starter pack
for i, item in ipairs(Player.Backpack:GetChildren()) do
  createItemFrame(tostring(i))
end

-- Create item frames every time a NEW item is added to backpack
local displayedItems = {}

Player.Backpack.ChildAdded:Connect(function(child)
    if not (child:IsA("Tool")) then return end
    if table.find(displayedItems, child) then return end

    table.insert(displayedItems, child)
    createItemFrame(child.Name)
end)
3 Likes
cloneItemFrame.Tool.Value = item.Name
cloneItemFrame.ImageLabel.Image = item.TextureId

there is no item value
image

1 Like
function createItemFrame(text, item)
  	local cloneItemFrame = ReplicatedStorage.Item:Clone()
	cloneItemFrame.TextLabel.Text = text
	cloneItemFrame.Tool.Value = item.Name
	cloneItemFrame.ImageLabel.Image = item.TextureId
	cloneItemFrame.Parent = Player.PlayerGui.Backpack.Frame;
	
	cloneItemFrame.ImageButton.MouseButton1Down:Connect(function() 
		local tool = Player.Backpack:FindFirstChild(cloneItemFrame.Tool.Value)
		local character = Player.Character or Player.Character:WaitForChild()
		local humanoid = character.Humanoid;
		
		local strokeFound = cloneItemFrame:FindFirstChild("UIStroke")
		
		if strokeFound then
			strokeFound:Destroy();
			humanoid:UnequipTools() 
			return;
		end
		
		for i, frame in ipairs(Player.PlayerGui.Backpack.Frame:GetChildren()) do
			for i, item in ipairs(frame:GetChildren()) do
				if item.Name == "UIStroke" then
					item:Destroy();
				end
			end
		end

		local stroke = Instance.new("UIStroke")
		stroke.Color = Color3.fromRGB(255, 255, 255);
		stroke.Parent = cloneItemFrame;
		stroke.Thickness = 2.1

		task.wait(0.10)
		humanoid:EquipTool(tool)
	end)
end

-- Create item frames for the tools which are replicated from starter pack
for i, item in ipairs(Player.Backpack:GetChildren()) do
  createItemFrame(tostring(i), item)
end

-- Create item frames every time a NEW item is added to backpack
local displayedItems = {}

Player.Backpack.ChildAdded:Connect(function(child)
    if not (child:IsA("Tool")) then return end
    if table.find(displayedItems, child) then return end

    table.insert(displayedItems, child)
    createItemFrame(child.Name, item)
end)

Touches its card correctly but the only problem is that the chicken does not want to be displayed but on the other hand there is an error in the console.

17:17:52.322 Workspace.MrQuestGO.Inventory:11: attempt to index nil with ‘Name’ - Client - Inventory:11
17:17:52.322 Stack Begin - Studio
17:17:52.322 Script ‘Workspace.MrQuestGO.Inventory’, Line 11 - function createItemFrame - Studio - Inventory:11
17:17:52.323 Script ‘Workspace.MrQuestGO.Inventory’, Line 59 - Studio - Inventory:59
17:17:52.323 Stack End -