Using one script to manage multiple tools

So currently I’m using one local script to manage few tools, for an example:

char.ChildAdded:Connect(function(child)
	if child:IsA("Tool") then
		Tool = child
	end
end)

Tool.Changed:Connect(function()
	if Tool.Parent ~= char then
		Tool = nil
	end
end)

Tool.Activated:Connect(function()
    Tool.Part.BrickColor = BrickColor.new("Really black")
    wait(3)
    Tool.Part.BrickColor = BrickColor.new("Reddish brown")
end)

However, this will cause an error if the player unequip the tool / change to the other tool immediately after he activated the tool because Tool will become nil, how could I avoid this?

I know this sounds like a really simple code logic problem… But I just can’t figure it out.

2 Likes

I’ve never really done something like this (one local script for multiple tools) as it is a lot easier to accomplish with a custom tool system with custom events but that being said you could probably do something like this:

local SetupTools = {}

local function SetupTool(Tool)
	
	if not Tool:IsA("Tool") then
		return
	end
	
	if SetupTools[Tool.Name] then -- If it has already been setup then do nothing.
		return
	end

	Tool.Activated:Connect(function()
		-- do stuff
	end)	
	
	SetupTools[Tool.Name] = Tool -- Store the tool in a table to keep track of it
end

for _, Tool in pairs(ToolLocation:GetChildren()) do -- ToolLocation could be the players backpack or a custom place
	SetupTool(Tool)
end

ToolLocation.ChildAdded:Connect(function()
	SetupTool(Tool)	
end)

-- Probably want to make sure you do proper cleanup of the table if a player respawns or dies such as clearing the table.
-- This is untested so you might have to tinker with it a little.

Do the tools use the same script?

Most likely yes.
I did consider using a table to store about tools, but I’m afraid that it will be too complicated because I have multiple variables regarding the child of the tool. But that’s probably the only way to do it for now. I’ll try it soon.

Thanks for your detailed solution, but I came up with an another simple solution to resolve this:
Instead of using arrays, I create a new temporary variable upon activate:

Tool.Activated:Connect(function()
    local temptool
    temptool = Tool
    temptool.Part.BrickColor = BrickColor.new("Really black")
    wait(3)
    temptool.Part.BrickColor = BrickColor.new("Reddish brown")
end)

You can also just simply add an

if Tool ~= nil then

before you run your activated code.

Creating a tool variable that sets itself to Tool immediately is the same thing as just using the Tool variable in the first place, if you follow my above suggestion your problem will resolve itself and account for any periods of time that Tool may be nil for any reason.

Not the best solution to my case, I ran multiple actions, if I have to call if everytime before I ran the action, it’s not efficient at all.

It is efficient; it is not going to affect performance in any noticeable manner (to check if the Tool is nil). You are kindly underestimating the power of lua.

Tool.Activated:Connect(function()
    if Tool ~= nil then
        Tool.Part.BrickColor = BrickColor.new("Really black")
        wait(3)
        Tool.Part.BrickColor = BrickColor.new("Reddish brown")
    end
end)

I’m actually working this to a gun system, if the player changes the tool/unequip after they shoot, it will result error because they change Tool to nil before the gun shooting process complete (Enabling muzzle flashes, playing sound etc.) For the code above, if the player unequip the tool within 2 seconds after he/she activates it, it will result an error since Tool will become nil.

For inefficient, the code will look like this and it still works:

if Tool ~= nil then
    Tool.Part.BrickColor = BrickColor.new("Really black")
    wait(3)
    if Tool ~= nil then
        Tool.Part.BrickColor = BrickColor.new("Reddish brown")
    end
end

That’s why I create a temporary variable instead, check out my thread above:

You are correct, you should use that answer. Also, I was wrong you actually don’t need to check on Tool.Activated because it already proved it’s not nil since tools can’t be activated while unequipped.

Actually, in this case it makes since to do that because you should always change the color back regardless of it was unequipped. Good job, I misunderstood your solution previously.

2 Likes