Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
✓ ANSWER ACCEPTED

How do i constantly check for changes in a player's backpack?

I can't find a way to constantly check the player's backpack for a new item that has been added such as when the player picks up a new tool. I tried using ChildAdded and ChildRemoved but those events activate every time an item gets added to the backpack which is a problem since when a player equips a tool, it gets added to the character model but when they equip it, it goes back to the backpack which then fires the event.

local player = game.Players.LocalPlayer
local char = player.Character
local myHum = char:WaitForChild('Humanoid')
local backPack = player:WaitForChild('Backpack')
local space = script.Space
local mainFrame = script.Parent:WaitForChild('MainFrame')
local selectedItem = script.Parent.SelectedItem
local inventory = {}

game.StarterGui:SetCoreGuiEnabled(Enum.CoreGuiType.Backpack,false) -- disable default backpack Gui

 
--//Search

function search(location)
    for i,v in pairs(location:GetChildren()) do
	    if v:IsA('Tool') then
		    table.insert(inventory,v)
	    end
	end
end



--//Add all current items in backpack to inventory

search(backPack)
search(char)

for i,v in pairs(inventory) do
    local clone = space:Clone()
    clone.Name = v.Name
    clone.LayoutOrder = i
    clone.Image = v.TextureId
    clone.Parent = mainFrame

--//Activated
clone.Activated:Connect(function()
selectedItem.Value = v

if v.Parent == backPack then
    myHum:EquipTool(v)
else
    myHum:UnequipTools()
	    end
    end)
end


--//Create Button

function create()

backPack.ChildAdded:Connect(function(child)

if child:IsA('Tool') then

local clone = space:Clone()

clone.Name = child.Name

clone.Image = child.TextureId

clone.Parent = mainFrame

end

end)

char.ChildAdded:Connect(function(child)

if child:IsA('Tool') then

local clone = space:Clone()

clone.Name = child.Name

clone.Image = child.TextureId

clone.Parent = mainFrame

end

end)

end



--//Constantly check for changes
while wait() do
    search(backPack)
    search(char)
    create()
end

5 comments

0

Sorry for the terrible code block, first time using this site in a while so i'm new to the changes.

0

what about using #backpack:GetChidren()?

0

change if that is changed and if so something added

0

You probably want to use ChildAdded, just keep track of what's new or not.

0

I did but that's not enough since the tool's parent switches from the character model to the backpack depending on whether it's equipped or not.

2 answers

✓ Accepted answer

Dictionaries

Tables have an array part and a dictionary part. The latter is a collection that is unordered which is a mapping of keys to values.

It generally looks like this

local d = {
	[key] = value,
	--// you can also do `key = value` if `key` is a valid identifier
};

You can index for value with d[key] or d.key (with the latter assuming key is a valid identifier).

So what you can do is add the name of the tool that is equipped to this dictionary part.

Something along the lines of this

local equippedTools = {};

And when a child is added to the backpack

if (child:IsA("Tool")) then
	if (not equippedTools[child.Name]) then
		equippedTools[child.Name] = true;
	end
end

What is happening

  • Check if the child added is a tool
    • Check that they are not in the dictionary already.
      • If not in the dictionary already, add to the dictionary.

Also as a side note don't use while wait() do. This idiom only works because of a hack; a trick.

Use

while true do
	...
	wait(t)
end

It's clearer. I also suggest a much longer wait time and you probably can use an event.

6 comments

0

thanks!

0

-1 for unflexibility, since checking names will only work with unique names. So, tools with the same name will not be considered new. Also, doesn't taken into account the parts that are added as the players load with the CharacterAdded function. How the hell do you have 2k reps with this many bugs?

0

You can't possibly be this bad. #1: tools will not have the same name #2: you would be using backpack not the character #3: ur a hypocrite

0

Tools can have the same names, dumbo. Also, the same thing applies to the backpack. I've already tested these, I wouldn't put forth claims without evidence behind them. I've tested each scenario I've put forth and your code just doesn't do the job. It's full of bugs, fix your code. Learn how to code.

0

Says the one who said while wait() do was better because it took up "less memory space" hypocrite smh. And if you have a nightstick and an Ak-47 as a weapon, you wouldn't name them both Ak-47 as it's misleading

0

There's a difference between the past and now stupid. It's all about the present and the future, not about what happened in the past. So, you making that claim is practically irrelevant to this scenario at hand. I am just awe-struck that you can't solve something so simple while seeming to be so confident.

Hey Sorukan,

You can accomplish this easily by using logic statements and a to see if the tool is new. You would just keep all the current Backpack tools in a table, and when a child is added check if the new child is equal to any of those tools in the table - if it is then it will be not a new tool. Here, let me just show the code rather than explain the whole thing with words:

local players = game:GetService("Players"); -- The Players Service

local tools_in_backpack = {}; -- A table that will keep all the tools. It can then check if the new tool exists in this table, and if they don't then that means it's a new tool.

local player = players.LocalPlayer; -- The Local Player
local backpack = player:WaitForChild("Backpack") -- The backpack

function set_table_to_tools() -- Sets the table to all the tools inside the backpack.
backpack = player:WaitForChild("Backpack") -- Updates backpack incase the player died.
    for _, tool in next, backpack:GetChildren() do -- A loop running through all the tools in the backpack to add them.
	    tools_in_backpack[#tools_in_backpack + 1] = tool; -- Adds the instance to the table.
	end
end

function fire_upon_newtool(child) -- A function that will fire everytime a new tool is added.
	if child:IsA("Tool") then -- Checks if what was added is a tool.
	    local new_tool = true; -- A boolean value that will be false if it's not a new tool that was added.

	    for _, tool in next, tools_in_backpack do -- Loops through the table above.
		    if tool == child then -- If any of the tools it is looping through in the table is equal to this new tool, then it's going to set new_tool to false to show that it's not a new tool.
			    new_tool = false; -- Sets new_tool to false because it's not a new tool.
		    end
	    end

    if new_tool then -- Checks if it's a new_tool
	    print("It's a new tool.") -- Code that will run if it's a new tool.
    end
    end
end

  

function characteradded_tools(char) -- A function to add all the tools that may be added as the Character is added, because those don't get added since this function is not yet recognized by the server.
    set_table_to_tools() -- Sets the table to the new tool that are added.
end

  

backpack.ChildAdded:Connect(fire_upon_newtool) -- Connects the ChildAdded event to the fire_upon_newtool function.
player.CharacterAdded:Connect(characteradded_tools) -- Connects the characteradded_tools function to the CharacterAdded event.

I hope I was of some help and please comment below if you have any questions!

Thanks, Best regards, IdealistDeveloper

2 comments

0

-1. Too many comments, makes it hard to read.

0

It's cool with me as long as others can understand the code. You can just delete the comments if you want ;3

This discussion is preserved as it was. New answers, comments, and votes are closed.