This is extremely complicated to explain, I'm trying to make a sheathe system that is tool based

I’m trying to make a tool based sheathe sword system I don’t want to just weld a basepart to the right hand. I want it as a tool, which I’m trying to find a way how to do that here’s exactly what my code is supposed to do in very valid detail.

So, the player first equips the sword, it’s supposed to make the meshparts in the tool invisible and it plays the equip animation, when the “weld” markerreachedsignal is fired the meshparts in the tool is supposed to turn back to visible. It finds the weaponmodel clone which is a basepart named “Longsword” aka (currentWeapon) and destroys it, to act as if we just welded it to the right hand, gives the illusion, we’re doing that because I want the illusion as it’s grabbing the sword from the players back when we equip it again.

Okay, so now the player unequips the sword, it plays the unequip animation, when the equipped weld markerreached signal is fired it makes the meshparts invisible and adds the weaponclone and welds it to the back giving the illusion the player is putting it on its back

When the player equips the sword, same thing, unequips same thing. Please help me

What’s happening is that when player first equips the sword, it’s making the meshparts invisible in the tool invisible, which is what I want and it plays the equip animation, when the “weld” markerreachedsignal is fired the meshparts in the and turns back to visible. It finds the weaponmodel clone which is a basepart named “Longsword” aka (currentWeapon) and destroys it. When I Unequip the sword, plays the animation then welds the sword to the back. When I equip the sword again, the meshparts don’t turn invisible at all it just turns visible for some reason.

Here’s my server script:

-- [[ Services ]] --
local RS = game:GetService("ReplicatedStorage")
local SoundService = game:GetService("SoundService")
local Debris = game:GetService("Debris")
local Players = game:GetService("Players")

-- [[ Folders ]] --
local Models = RS.Models
local WeaponsModels = Models.Weapons
local WeaponsWeld = script.Welds.Weapons
local Events = RS.Events
local AnimationsFolder = RS.Animations
local WeaponsAnimations = AnimationsFolder.Weapons
local WeaponsSounds = SoundService.SFX.Weapons
local RSModules = RS.Modules

-- [[ Events ]] --
local WeaponsEvent = Events.WeaponsEvent

-- [[ Modules ]] --
local SoundsModule = require(RSModules.Combat.SoundsModule)

-- [[ Objects ]] --
local Welds = {}

-- [[ Animations ]] --
local EquipAnims = {}
local UnEquipAnims = {}
local IdleAnims = {}

-- [[ Values ]] --
local EquipDebounce = {}

---------------------------------------------------------------------------------------------------------------------------------------------------------

Players.PlayerAdded:Connect(function(plr)

    plr.CharacterAdded:Connect(function(char)
        local torso = char.Torso

        -- Initialize attributes for the player
        char:SetAttribute("Equipped", false)
        char:SetAttribute("CurrentWeapon", "Longsword")

        -- You can leave the welding structure setup here (if necessary) without cloning the weapon
        Welds[plr] = nil -- Or any other setup if needed, but avoid cloning weapon here
    end)

end)

Players.PlayerRemoving:Connect(function(plr)
    if Welds[plr] then
        -- Clean up the weld when the player leaves
        table.remove(Welds, table.find(Welds, Welds[plr]))
    end
end)

WeaponsEvent.OnServerEvent:Connect(function(plr, action, currentWeapon)
    local char = plr.Character
    local hum = char:WaitForChild("Humanoid")
    local torso = char.Torso
	local rightArm = char["Right Arm"]
	local toolName = char:FindFirstChild("Longsword") 

    if currentWeapon and WeaponsModels:FindFirstChild(currentWeapon) then
        if action == "Equipped" and not char:GetAttribute("Equipped") and not EquipDebounce[plr] then
			EquipDebounce[plr] = true
			
			if toolName and toolName:IsA("Tool") then
				for _, part in ipairs(toolName:GetDescendants()) do
					if part:IsA("MeshPart") then
						part.Transparency = 1
					end
				end
			end
			
            SoundsModule.PlaySound(WeaponsSounds[currentWeapon].Main.Equip, torso)
            IdleAnims[plr] = hum.Animator:LoadAnimation(WeaponsAnimations[currentWeapon].Main.Idle)
            EquipAnims[plr] = hum.Animator:LoadAnimation(WeaponsAnimations[currentWeapon].Main.Equip)
            EquipAnims[plr]:Play()

            EquipAnims[plr]:GetMarkerReachedSignal("Weld"):Connect(function()
				if not Welds[plr] then
					Welds[plr] = WeaponsWeld[currentWeapon].HoldingWeaponWeld:Clone()
					Welds[plr].Parent = rightArm
				end
				
				Welds[plr].Part0 = rightArm
				Welds[plr].C1 = WeaponsWeld[currentWeapon].HoldingWeaponWeld.C1
				
				if toolName and toolName:IsA("Tool") then
				for _, part in ipairs(toolName:GetDescendants()) do
					if part:IsA("MeshPart") then
							part.Transparency = 0
							end
						end
				end
				
				
				local weaponInstance = char:FindFirstChild(currentWeapon)
				if weaponInstance and weaponInstance:IsA("BasePart") then
					-- If the weapon is a BasePart (MeshPart, Part, etc.), destroy it
					weaponInstance:Destroy()
					
				end
			end)

            EquipAnims[plr]:GetMarkerReachedSignal("Equipped"):Connect(function()
                IdleAnims[plr]:Play()
                char:SetAttribute("Equipped", true)
                EquipDebounce[plr] = false
            end)
        elseif action == "UnEquipped" and char:GetAttribute("Equipped") and not EquipDebounce[plr] then
            EquipDebounce[plr] = true
            SoundsModule.PlaySound(WeaponsSounds[currentWeapon].Main.UnEquip, torso)
            IdleAnims[plr]:Stop()
            UnEquipAnims[plr] = hum:LoadAnimation(WeaponsAnimations[currentWeapon].Main.UnEquip)
            UnEquipAnims[plr]:Play()

            UnEquipAnims[plr]:GetMarkerReachedSignal("Weld"):Connect(function()
                Welds[plr].Part0 = torso
				Welds[plr].C1 = WeaponsWeld[currentWeapon].IdleWeaponWeld.C1
				
				local weaponClone = WeaponsModels[currentWeapon]:Clone()
				weaponClone.Parent = char
				weaponClone.Name = currentWeapon

				-- Initialize weld if it doesn't exist for unequipping
				if not Welds[plr] then
					Welds[plr] = WeaponsWeld[currentWeapon].IdleWeaponWeld:Clone()
					Welds[plr].Parent = torso
				end
				Welds[plr].Part0 = torso
				Welds[plr].Part1 = weaponClone
				
            end)

            UnEquipAnims[plr]:GetMarkerReachedSignal("UnEquipped"):Connect(function()
                char:SetAttribute("Equipped", false)
                EquipDebounce[plr] = false
            end)
        end
    end
end)

Here’s my local script:

local tool = script.Parent
local RS = game:GetService("ReplicatedStorage")
local WeaponsEvent = RS.Events:WaitForChild("WeaponsEvent")

-- Get the name of the weapon from the tool
local weaponName = tool.Name

-- Function to handle tool equip
local function onEquip()
	local plr = game.Players.LocalPlayer
	if plr then
		WeaponsEvent:FireServer("Equipped", weaponName)
		print("Equipped")
	end
end

-- Function to handle tool unequip
local function onUnequip()
	local plr = game.Players.LocalPlayer
	if plr then
		WeaponsEvent:FireServer("UnEquipped", weaponName)
		print("UnEquipped")
	end
end

tool.Equipped:Connect(onEquip)
tool.Unequipped:Connect(onUnequip)

The weaponsmodel is a basepart named Longsword and currentWeapon is just the name of the weapon.