I basically need a way to determine if a tool was equipped or swapped, the only way I can think to do this would be to record the time difference between the removal of one and addition of the other?
The purpose is certain tools will behave differently when swapped to another as opposed to de-equipping the tool all together and equipping the other one. There’s an extra step in the middle which will change the behaviour.
The default Tool class does not have this function, and implementing it can be very hacky that it’s probably better to work with a custom (or backpack) implementation.
Anyways, I’ve made a server Script to implement a hacky method with explanations in the code itself. I tested this with a LocalScript and behaves the same way, but I have only tested this on studio, not on a live server:
--!strict
-- Equipped method by keeping track of the number of tools
-- in our backpack and comparing it whenever we equip the tool
if script.Parent.Parent.Parent.ClassName == "Player" then
local player: Player = script.Parent.Parent.Parent
local backpack: Backpack = player:FindFirstChildOfClass("Backpack") :: Backpack
local numberOfTools: number = 0
-- function to count the number of tools in our backpack
local function countTools(): number
local total: number = 0
for _: number, instance: Instance in backpack:GetChildren() do
if instance.ClassName == "Tool" then
total += 1
end
end
return total
end
-- function to update the number of tools in our backpack
local function updateNumberOfTools(): ()
-- we defer it so when Equipped gets fired, we can get the
-- previously number of tools and compare it to the new one
task.defer(function(): ()
numberOfTools = countTools()
end)
end
-- update the number of tools and hook it onto our backpack
-- listener for ChildAdded and ChildRemoving
updateNumberOfTools()
backpack.ChildAdded:Connect(updateNumberOfTools)
backpack.ChildRemoved:Connect(updateNumberOfTools)
-- Equipped event listener
script.Parent.Equipped:Connect(function(): ()
-- get the number of tools before the Equipped event
local toolCountBeforeEquipped: number = numberOfTools
-- we compare of the number of tools before the Equipped event
-- minus 1 (since this tool moved itself out of the backpack)
-- to the new number of tools in our backpack. If it does not
-- match, that means we equipped normally and no previous tool
-- went back into our backpack. if it matches, that means a
-- previous tool has been added back into the backpack via
-- unequpping
if toolCountBeforeEquipped - 1 == countTools() then
print("Equipped normally")
else
print("Swapped into")
end
end)
end
-- Unequipped method by checking if a new tool has been equipped
-- when we uneqipped this tool
script.Parent.Unequipped:Connect(function(): ()
if script.Parent.Parent.Parent.ClassName == "Player" then
local character: Model? = (script.Parent.Parent.Parent :: Player).Character
local tool: Tool? = if character ~= nil then character:FindFirstChildOfClass("Tool") else nil
if tool ~= nil then
print("Swapped away")
else
print("Unequipped normally")
end
end
end)
Do note that in the end, if you’re trying to do something like swapping out animations, this method will not be possible unless you have a custom model outside of your Tool that is animating since it immediately goes back into your backpack upon unequipping, which at that point it would serve you well if you just made your own tool and/or backpack implementation.
local PreviousTool = ""
game.Players.LocalPlayer.Character.ChildAdded:Connect(function(Child)
if not Child:IsA("Tool") then return end
if Child.Name == PreviousTool then
-- player equipped the same tool
elseif PreviousTool ~= "" then
-- player equipped a different tool
if game.Players.LocalPlayer.Backpack:FindFirstChild(PreviousTool) then
-- player most likely swapped tools
else
-- player most likely dropped the previous tool
end
end; PreviousTool = Child.Name
end)