How to fix Equipping system

hey so im relatively new to scripting and im having trouble with this combat see im trying to stop the player from being able to attack with the sword not equipped any help would be appreciated and here is the code
LOCAL SCRIPT

local Sword = rp.Remotes:WaitForChild("Swords")

local UIS = game:GetService("UserInputService")
local isEquipped = false
local debounce = false
local cd = 1
local Unsheathe = rp.Sounds:WaitForChild("Unsheathe")
local sheathe = rp.Sounds:WaitForChild("Sheathe")
local Players = game:GetService("Players")
local player = Players.LocalPlayer
local char = player.Character
local IsEquipped = char:GetAttribute("isEquipped")

char:SetAttribute("isEquipped" ,false)
UIS.InputBegan:Connect(function(input,isTyping)
	 
	
 
	if not isTyping then
		if input.KeyCode == Enum.KeyCode.E then
			if not isEquipped and not debounce then
				isEquipped = true
				Sword:FireServer(isEquipped)
				char:SetAttribute("isEquipped" ,true)
			elseif isEquipped and not debounce then
				debounce = true
				isEquipped = false
				Sword:FireServer(isEquipped)
				char:SetAttribute("isEquipped" ,false)
				
			end

	
		end
	end
end)

Sword.OnClientEvent:Connect(function()
	wait(cd)
	debounce = false
end)```
4 Likes

This script looks fine, is there another script that actually handles the attacking?

Can you try this?

-- Constants
local CONSTANTS = {
    REMOTE_EVENT_NAME = "Swords",
    UNSHEATHE_SOUND_NAME = "Unsheathe",
    SHEATHE_SOUND_NAME = "Sheathe",
    EQUIP_ATTRIBUTE_NAME = "isEquipped",
    TOGGLE_KEY = Enum.KeyCode.E,
    DEBOUNCE_MESSAGE = "Debounce is active, cannot toggle equip state",
    TYPING_MESSAGE = "User is typing, input ignored",
    CHARACTER_ERROR = "Character is not available",
    ASSET_ERROR = "Required assets are missing from ReplicatedStorage",
    INIT_ERROR = "Initialization error: "
}

-- Services
local UserInputService: UserInputService = game:GetService("UserInputService")
local Players: Players = game:GetService("Players")

-- Remote Event
local Sword: RemoteEvent = game.ReplicatedStorage.Remotes:WaitForChild(CONSTANTS.REMOTE_EVENT_NAME)

-- Sounds
local Sounds: {Unsheathe: Sound, Sheathe: Sound} = {
    Unsheathe = game.ReplicatedStorage.Sounds:WaitForChild(CONSTANTS.UNSHEATHE_SOUND_NAME),
    Sheathe = game.ReplicatedStorage.Sounds:WaitForChild(CONSTANTS.SHEATHE_SOUND_NAME)
}

-- Player and Character
local player: Player = Players.LocalPlayer
local character: Model = player.Character or player.CharacterAdded:Wait()

-- State Variables
local isEquipped: boolean = false
local debounce: boolean = false
local cooldown: number = 1

-- Function to handle equipping and unequipping
local function toggleEquip()
    if debounce then
        return CONSTANTS.DEBOUNCE_MESSAGE
    end

    debounce = true
    isEquipped = not isEquipped
    character:SetAttribute(CONSTANTS.EQUIP_ATTRIBUTE_NAME, isEquipped)
    Sword:FireServer(isEquipped)

    -- Play sound based on equip state
    (Sounds[isEquipped and "Unsheathe" or "Sheathe"]):Play()

    task.wait(cooldown)
    debounce = false
end

-- Input Handling
local function onInputBegan(input: InputObject, isTyping: boolean)
    if isTyping then
        return CONSTANTS.TYPING_MESSAGE
    end

    if input.KeyCode == CONSTANTS.TOGGLE_KEY then
        toggleEquip()
    end
end

UserInputService.InputBegan:Connect(onInputBegan)

-- Remote Event Handling
Sword.OnClientEvent:Connect(function()
    task.wait(cooldown)
    debounce = false
end)

-- Top-level error handling
local success, err = pcall(function()
    -- Ensure character is available
    if not character then
        error(CONSTANTS.CHARACTER_ERROR)
    end

    -- Ensure remote event and sounds are available
    if not Sword or not Sounds.Unsheathe or not Sounds.Sheathe then
        error(CONSTANTS.ASSET_ERROR)
    end
end)

if not success then
    warn(CONSTANTS.INIT_ERROR .. err)
end