How to destroy a tool from player

OK, so I have the code working for removing tools from the backpack. This is running great. Thanks for all of the dev forum samples to guide me.The problem comes up if the tool is active. When active the tool gets removed from Backpack and is moved to the player???. Because the tool is no longer in the backpack it gets overlooked by the delete I have setup. What would be the recommended way to destroy a tool that is selected.

local backpack = player.Backpack
local ChickenFind = backpack:FindFirstChild(“LauncherChicken”)
local DogeFind = backpack:FindFirstChild(“LauncherDoge”)
local CatFind = backpack:FindFirstChild(“LauncherCat”)
local FishFind = backpack:FindFirstChild(“LauncherFish”)
local RodanFind = backpack:FindFirstChild(“LauncherRodan”)
local DemoFind = backpack:FindFirstChild(“LauncherDemo”)

local LaunchersToRemove = {ChickenFind, DogeFind, CatFind, FishFind, RodanFind, DemoFind}

for _,v in pairs(LaunchersToRemove) do
for i, tool in pairs(backpack:GetChildren()) do
if tool.Name == v.Name then
tool:Destroy()
end
end
end

10 Likes

When active, a tool’s parent is set as the player’s character. You can create a for loop to loop through the player’s character to look for any tools.

for _,v in pairs(player.Character:GetChildren()) do
    if v:IsA("Tool") then
        -- you've found a tool in the character!
    end
end
7 Likes

For cases like this, I typically create a reusable function that I run twice over. I obviously have vastly different use cases and don’t often or at all use the code below, but I’ll present it for the sake of answering the question. Essentially, it’s a conversion of your current code into a function that’s ran across two different containers.

I’d also clean up your table some. You’re holding unnecessary references to objects.

local backpack = player:WaitForChild("Backpack") -- Not inserted immediately
local character = player.Character or player.CharacterAdded:Wait()

local removableLaunchers = {"LauncherChicken", "LauncherDoge", "LauncherCat", "LauncherFish", "LauncherRodan", "LauncherDemo"}

local function purgeLaunchers(container)
    for _, launcher in pairs(removableLaunchers) do
        local tool = container:FindFirstChild(launcher)
        if tool and tool:IsA("Tool") then
            tool:Destroy()
        end
    end
end

purgeLaunchers(backpack)
purgeLaunchers(character)

In the instance that you simply want to remove all launchers outright, I’d forego the table and instead hanker towards string matching. If any tool has the name launcher in it, remove it. This simply changes the function a bit, the rest stays the same.

local backpack = player:WaitForChild("Backpack")
local character = player.Character or player.CharacterAdded:Wait()

local function purgeLaunchers(container)
    for _, item in pairs(container:GetChildren()) do
        if item:IsA("Tool") and item.Name:match("Launcher") then
            item:Destroy()
        end
    end
end

purgeLaunchers(backpack)
purgeLaunchers(character)

And like so, you can get rid of equipped or unequipped launchers with the same code but different containers. If your aim is to remove all launchers, I prefer using the second code sample over the first because then you can get rid of all launchers without needing to manually update a table each time you add a new launcher to your game. Always go for options that are more scalable and automated.

You can also modify the purgeLaunchers function to pass a list of containers, to which the function will iterate through those containers and call the related code to remove them. I won’t show you how to do that, but it essentially just makes your code writing more of eye candy by doing:

purgeLaunchers({backpack, character})
-- purgeLaunchers{backpack, character} also works due to the way syntax is handled
11 Likes

For the player:
Since only one tool can be equipped at a time, you can just use FindFirstChildOfClass()

local function PurgeLaunchers() --excuse the function format if it's not entirely useful here
	local player = game.Players.LocalPlayer or player--not sure if it's a localscript or a serverscript
	local container = player.Character
	local tool = container:FindFirstChildOfClass("Tool") 
	if tool then --separate checking for name from checking for existence to avoid errors
		if removableLaunchers[tool.Name] then --if the tool's name is within the table, can't test so it hopefully doesn't error
			tool:Destroy() 
		end
	end
	
	container = player.Backpack
	
	--example 1
	for i,tool in pairs(container:GetChildren()) do
		if removableLaunchers[tool.Name] then --if the tool's name is within the table, can't test so it hopefully doesn't error again
			tool:Destroy()
		end
	end
	
	--example 2
	container:ClearAllChildren()
end

PurgeLaunchers()

I couldn’t test the code properly so i hope it works either way. example 1 and 2 are separate by only one thing: 1 checks if the tool is within the table, 2 just clears the backpack. this still depends on the assumption that removableLaunchers[tool.Name] doesn’t throw an error. Hope that helps.

6 Likes

Finding multiple tools accounts for potential edge cases wherein more than one tool exists in the player, which is possible. In a normal environment though this typically doesn’t happen and the function I proposed can be modified to check and remove a tool if a Tool instance is passed, otherwise use the iteration method mentioned before.

Your code has two issues.

  • You attempt to search for a tool in the removableLaunchers table using the tool’s name as an indice. My table is not a dictionary. The indice of tool.Name is nil. This does nothing.

  • ClearAllChildren is typically not a good idea since other items can exist, other than tools, in Backpack. Unless you’re sure about it’s usage, it’s much better to remove based on a certain criteria. Other tools may exist alongside the launchers.

4 Likes

This works great!!! I’ve been testing it and it works every time. I appreciate your time in writing the code.

local backpack = player:WaitForChild(“Backpack”)
local character = player.Character or player.CharacterAdded:Wait()

local function purgeLaunchers(container)
for _, item in pairs(container:GetChildren()) do
if item:IsA(“Tool”) and item.Name:match(“Launcher”) then
item:Destroy()
end
end
end

purgeLaunchers(backpack)
purgeLaunchers(character)

5 Likes

Okay, notes taken. thanks for your input.

2 Likes