Okay, let me just drop the full code:
Server:
local Tool = script.Parent
-- Initializing--------------------------------------------------------------------------
local HumanoidFromBackpack
local PlayerFromBackpack
if script.Parent.Parent:IsA("Backpack") then
HumanoidFromBackpack = script.Parent.Parent.Parent.Character:WaitForChild("Humanoid")
PlayerFromBackpack = script.Parent.Parent.Parent
end
local Character = PlayerFromBackpack.Character or PlayerFromBackpack.CharacterAdded:Wait()
local Animations = Character:WaitForChild("Animations")
local Animator = HumanoidFromBackpack:WaitForChild("Animator")
local BlockHitBlocker : AnimationTrack = Animator:LoadAnimation(Animations["Impacts"]:WaitForChild("BlockHitBlocker"))
local BlockHitSwinger : AnimationTrack = Animator:LoadAnimation(Animations["Impacts"]:WaitForChild("BlockHitSwinger"))
local PBHitBlocker : AnimationTrack = Animator:LoadAnimation(Animations["Impacts"]:WaitForChild("PBHitBlocker"))
local PBHitSwinger : AnimationTrack = Animator:LoadAnimation(Animations["Impacts"]:WaitForChild("PBHitSwinger"))
BlockHitBlocker:Play() BlockHitSwinger:Play() PBHitBlocker:Play() PBHitSwinger:Play()
BlockHitBlocker:Stop() BlockHitSwinger:Stop() PBHitBlocker:Stop() PBHitSwinger:Stop()
----------------------------------------------------------------------------------------
local Hit = script.Parent:WaitForChild("Hit")
local Block = script.Parent:WaitForChild("Block")
local Kick = script.Parent:WaitForChild("Kick")
local Handle = Tool:WaitForChild("Handle")
local HitboxClass = require(game:GetService("ReplicatedStorage"):WaitForChild("HitboxClass"))
local HitboxTypes = require(game:GetService("ReplicatedStorage"):WaitForChild("HitboxClass"):WaitForChild("Types"))
local SwordHitboxParams = {
SizeOrPart = script.Parent.Hitbox,
DebounceTime = .4,
UseClient = PlayerFromBackpack,
Debug = true
} :: HitboxTypes.HitboxParams
local KickHitboxParams = {
SizeOrPart = 3,
DebounceTime = 4,
UseClient = PlayerFromBackpack,
Debug = true
} :: HitboxTypes.HitboxParams
local SwordHitbox, SwordConnected = HitboxClass.new(SwordHitboxParams)
SwordHitbox:WeldTo(script.Parent:WaitForChild("Hitbox"))
repeat task.wait() until HumanoidFromBackpack.Parent:WaitForChild("Left Leg"):FindFirstChild("DmgPoint")
local KickHitbox, KickConnected = HitboxClass.new(KickHitboxParams)
KickHitbox:WeldTo(HumanoidFromBackpack.Parent:WaitForChild("Left Leg"), CFrame.new(0,-1,0))
local SwingDB = false
local KickDB = false
local BlockDB = false
local Unequipping = false
local Equipped = false
local SheithMesh = Handle:Clone()
SheithMesh.Parent = workspace
SheithMesh.CFrame = HumanoidFromBackpack.Parent:WaitForChild("Torso"):WaitForChild("Sheith").WorldCFrame * CFrame.Angles(math.rad(180),0,0) * CFrame.new(1,0,0)
SheithMesh.CanCollide = false
SheithMesh.Parent = HumanoidFromBackpack.Parent:WaitForChild("Torso")
SheithMesh.WeldConstraint.Part1 = HumanoidFromBackpack.Parent:WaitForChild("Torso")
SheithMesh = SheithMesh:WaitForChild("SwordMesh")
local UnequipMesh = Handle:Clone()
UnequipMesh.Parent = workspace
UnequipMesh.CFrame = HumanoidFromBackpack.Parent:WaitForChild("Right Arm"):WaitForChild("RightGripAttachment").WorldCFrame * CFrame.Angles(math.rad(90),math.rad(180),math.rad(-90)) * CFrame.new(2.2,0,0)
UnequipMesh.CanCollide = false
UnequipMesh.Parent = HumanoidFromBackpack.Parent:WaitForChild("Right Arm")
UnequipMesh.WeldConstraint.Part1 = HumanoidFromBackpack.Parent:WaitForChild("Right Arm")
UnequipMesh = UnequipMesh:WaitForChild("SwordMesh")
UnequipMesh.Transparency = 1
local PlayerValues = script.Parent.Parent.Parent:FindFirstChild("PlayerValues") or game:GetService("Players"):GetPlayerFromCharacter(script.Parent.Parent):FindFirstChild("PlayerValues")
local Blocking = PlayerValues:WaitForChild("Blocking")
local Swinging = PlayerValues:WaitForChild("Swinging")
local PBWindow = PlayerValues:WaitForChild("PBWindow")
local Dashing = PlayerValues:WaitForChild("Dashing")
local Sprinting = PlayerValues:WaitForChild("Sprinting")
local WeaponEquipped = PlayerValues:WaitForChild("WeaponEquipped")
-- Particles:
local ParticleEmitter = Handle:WaitForChild("ParticleEmitter")
local BlockParticle = ParticleEmitter:WaitForChild("Block")
local PBParticle = ParticleEmitter:WaitForChild("Block PERF")
local Trail = Handle:WaitForChild("Trail")
local PBDamage = 20 -- Damage dealt to the player swinging
local BlockDamage = 15 -- Damage dealt to the player blocking
local config = require(Tool:WaitForChild("Configuration"))
local SwingCycle = 1
local BlockBreakBindable = game:GetService("ServerStorage"):WaitForChild("ServerRemotes"):WaitForChild("BlockBreak")
local walk = HumanoidFromBackpack.Parent:WaitForChild("Animate").walk
Tool.Equipped:Connect(function()
repeat task.wait() until not Unequipping
if not Tool.Parent:FindFirstChild("Humanoid") then return end
walk.WalkAnim.AnimationId = "rbxassetid://140196428386220"
local clone = walk.WalkAnim:Clone()
walk.WalkAnim:Destroy()
clone.Parent = walk
Trail.Enabled = true
WeaponEquipped.Value = true
KickDB = false
SwingDB = false
if Sprinting.Value then
Sprinting.Value = false
end
task.wait(0.733) -- length of animation
Trail.Enabled = false
end)
local PBWindowDebounceCountdownTimer = 0
local PBWindowDebounceCountdownCooldownTimer = 0
task.spawn(function()
while task.wait(.1) do
PBWindowDebounceCountdownTimer = math.clamp(PBWindowDebounceCountdownTimer - .1, 0, math.huge)
PBWindowDebounceCountdownCooldownTimer = math.clamp(PBWindowDebounceCountdownCooldownTimer - .1, 0, math.huge)
if PBWindowDebounceCountdownTimer > 0 then
PBWindow.Value = true
else
PBWindow.Value = false
end
end
end)
local UnequipDebounceCountdownTimer = 0
task.spawn(function()
while task.wait(.1) do
UnequipDebounceCountdownTimer = math.clamp(UnequipDebounceCountdownTimer - .1, 0, math.huge)
if UnequipDebounceCountdownTimer > 0 then
Unequipping = true
else
Unequipping = false
end
end
end)
script.Parent.Unequipped:Connect(function()
WeaponEquipped.Value = false
Trail.Enabled = true
KickDB = true
SwingDB = true
BlockLogic(PlayerFromBackpack, false, .3)
UnequipDebounceCountdownTimer = 1.2
task.wait(1.2)
walk.WalkAnim.AnimationId = "rbxassetid://81889719929984"
local clone = walk.WalkAnim:Clone()
walk.WalkAnim:Destroy()
clone.Parent = walk
Trail.Enabled = false
end)
SwordHitbox.HitSomeone:Connect(function(HitCharacters)
for _, HitCharacter in pairs(HitCharacters) do
if HitCharacter == HumanoidFromBackpack.Parent then return end
local HitHumanoid = HitCharacter:FindFirstChild("Humanoid")
local HitPlayer = game:GetService("Players"):GetPlayerFromCharacter(HitCharacter)
if not HitPlayer then -- Dummies
if config.Damage == -1 then
HitHumanoid.Health = 0
else
HitHumanoid:TakeDamage(config.Damage)
end
return
end
local HitPlayerValues = HitPlayer:WaitForChild("PlayerValues")
local BlockingValue = HitPlayerValues["Blocking"].Value
local PBingValue = HitPlayerValues["PBWindow"].Value
if BlockingValue or PBingValue then
SwordHitbox:Stop()
end
if BlockingValue and PBingValue then
HumanoidFromBackpack:TakeDamage(PBDamage)
local SelfTrack : AnimationTrack = Animator:LoadAnimation(Animations:WaitForChild("Impacts"):WaitForChild("PBHitSwinger"))
SelfTrack.Looped = false
SelfTrack:Play()
local OpponentTrack : AnimationTrack = Animator:LoadAnimation(Animations:WaitForChild("Impacts"):WaitForChild("PBHitBlocker"))
OpponentTrack.Looped = false
OpponentTrack:Play()
ParticleEmit("PerfectBlock")
return
elseif BlockingValue and not PBingValue then
HumanoidFromBackpack:TakeDamage(BlockDamage)
local SelfTrack : AnimationTrack = Animator:LoadAnimation(Animations:WaitForChild("Impacts"):WaitForChild("BlockHitSwinger"))
SelfTrack.Looped = false
SelfTrack:Play()
ParticleEmit("Block")
local OpponentTrack : AnimationTrack = HitHumanoid:LoadAnimation(Animations:WaitForChild("Impacts"):WaitForChild("BlockHitBlocker"))
OpponentTrack.Looped = false
OpponentTrack:Play()
return
end
if config.Damage == -1 then
HitHumanoid.Health = 0
else
HitHumanoid:TakeDamage(config.Damage)
end
end
end)
Hit.OnServerEvent:Connect(function(Player)
if not SwingDB and not Dashing.Value and not Unequipping then
SwingDB = true
if Blocking then
BlockLogic(Player, false, 0.1)
end
SwordHitbox:Start()
Swinging.Value = true
local swingConfig = config["Swing" .. SwingCycle]
if swingConfig then task.wait(swingConfig.AttackTime) end
Swinging.Value = false
SwordHitbox:Stop()
SwingCycle += 1
task.wait(swingConfig.Cooldown)
if SwingCycle > 4 then SwingCycle = 1 end
SwingDB = false
end
end)
function BlockLogic(Player, Boolean, TweenTime)
if Boolean then
repeat task.wait() until not BlockDB
if Swinging.Value then
Swinging.Changed:Wait()
end
Blocking.Value = true
if PBWindowDebounceCountdownCooldownTimer == 0 then
PBWindowDebounceCountdownTimer = config.PerfectBlockDebounceTime
PBWindowDebounceCountdownCooldownTimer = config.PerfectBlockDebounceTime * 3
end
else
-- Stop the block animation if it's playing
Blocking.Value = false
task.spawn(function()
if BlockDB then return end
BlockDB = true
task.wait(.15)
BlockDB = false
end)
end
end
Block.OnServerEvent:Connect(BlockLogic)
KickHitbox.HitSomeone:Connect(function(HitCharacters)
for _, HitCharacter in HitCharacters do
if HitCharacter == HumanoidFromBackpack.Parent then return end
local HitHumanoid = HitCharacter:WaitForChild("Humanoid")
local HitPlayer = game:GetService("Players"):GetPlayerFromCharacter(HitCharacter)
HitHumanoid:TakeDamage(config.Kick.KickDamage)
if not HitPlayer then return end
if HitPlayer:WaitForChild("PlayerValues").Blocking.Value then
BlockBreakBindable:Fire(HitPlayer)
end
end
end)
BlockBreakBindable.Event:Connect(function(Player)
if Player == PlayerFromBackpack then
Player.PlayerValues.Blocking.Value = false
BlockLogic(Player, false, .3)
end
end)
Kick.OnServerEvent:Connect(function(Player)
if Blocking.Value then return end
if not KickDB and not SwingDB and not Dashing.Value then
SwingDB = true
KickDB = true
KickHitbox:Start()
HumanoidFromBackpack.WalkSpeed = 26
task.wait(config.Kick.AttackTime)
HumanoidFromBackpack.WalkSpeed = 16
SwingDB = false
KickHitbox:Stop()
task.wait(config.Kick.Cooldown)
KickDB = false
end
end)
function ParticleEmit(ParticleName : string)
if ParticleName == "PerfectBlock" then
for _, Particle in pairs(PBParticle:GetDescendants()) do
if Particle:IsA("ParticleEmitter") then
Particle:Emit(Particle:GetAttribute("EmitCount"))
end
end
elseif ParticleName == "Block" then
for _, Particle in pairs(BlockParticle:GetDescendants()) do
if Particle:IsA("ParticleEmitter") then
Particle:Emit(Particle:GetAttribute("EmitCount"))
end
end
end
end
Swinging.Changed:Connect(function(Bool)
if Bool then
Trail.Enabled = true
else
Trail.Enabled = false
end
end)
Dashing.Changed:Connect(function(Bool)
if Bool then
BlockLogic(PlayerFromBackpack, false, .1)
SwordHitbox:Stop()
end
end)
HumanoidFromBackpack.Died:Connect(function()
SwordHitbox:Stop()
KickHitbox:Stop()
SwordHitbox:ClearTaggedChars()
KickHitbox:ClearTaggedChars()
SwordHitbox:Destroy()
KickHitbox:Destroy()
end)
Client:
local Tool = script.Parent
local Handle = Tool:WaitForChild("Handle")
local Hit = Tool:WaitForChild("Hit")
local Block = Tool:WaitForChild("Block")
local Kick = Tool:WaitForChild("Kick")
local Mouse = game:GetService("Players").LocalPlayer:GetMouse()
local UserInputService = game:GetService("UserInputService")
local Player = game:GetService("Players").LocalPlayer
local Character = Player.Character or Player.CharacterAdded:Wait()
local Humanoid = Character:WaitForChild("Humanoid")
local SwingDB = false
local KickDB = false
local BlockDB = false
local Unequipping = false
local Equipped = false
local SwingCycle = 1
local CurrentSwingAnimation : AnimationTrack = nil -- Store reference to the current animation
local EquipAnimation = nil
local UnequipAnimation = nil
local SheithMesh = Character:WaitForChild("Torso"):WaitForChild("Handle"):WaitForChild("SwordMesh")
local UnequipSwordMesh = Character:WaitForChild("Right Arm"):WaitForChild("Handle"):WaitForChild("SwordMesh")
-- INIT
local Animator = Humanoid:WaitForChild("Animator")
task.wait(1)
local Animations = Character:WaitForChild("Animations")
local Swing1 : AnimationTrack = Animator:LoadAnimation(Animations["Swings"]:WaitForChild("1"))
local Swing2 : AnimationTrack = Animator:LoadAnimation(Animations["Swings"]:WaitForChild("2"))
local Swing3 : AnimationTrack = Animator:LoadAnimation(Animations["Swings"]:WaitForChild("3"))
local Swing4 : AnimationTrack = Animator:LoadAnimation(Animations["Swings"]:WaitForChild("4"))
local BlockHitBlocker : AnimationTrack = Animator:LoadAnimation(Animations["Impacts"]:WaitForChild("BlockHitBlocker"))
local BlockHitSwinger : AnimationTrack = Animator:LoadAnimation(Animations["Impacts"]:WaitForChild("BlockHitSwinger"))
local PBHitBlocker : AnimationTrack = Animator:LoadAnimation(Animations["Impacts"]:WaitForChild("PBHitBlocker"))
local PBHitSwinger : AnimationTrack = Animator:LoadAnimation(Animations["Impacts"]:WaitForChild("PBHitSwinger"))
local BlockAnimation : AnimationTrack = Animator:LoadAnimation(Animations:WaitForChild("Specials"):WaitForChild("Block"))
local Equip : AnimationTrack = Animator:LoadAnimation(Animations["Equips"]:WaitForChild("Equip"))
local Unequip : AnimationTrack = Animator:LoadAnimation(Animations["Equips"]:WaitForChild("Unequip"))
Swing1:Play() Swing2:Play() Swing3:Play() Swing4:Play() BlockHitBlocker:Play() BlockHitSwinger:Play() PBHitBlocker:Play() PBHitSwinger:Play() BlockAnimation:Play() Equip:Play() Unequip:Play()
Swing1:Stop() Swing2:Stop() Swing3:Stop() Swing4:Stop() BlockHitBlocker:Stop() BlockHitSwinger:Stop() PBHitBlocker:Stop() PBHitSwinger:Stop() BlockAnimation:Stop() Equip:Stop() Unequip:Stop()
----------------
local PlayerValues = Tool.Parent.Parent:FindFirstChild("PlayerValues") or game:GetService("Players"):GetPlayerFromCharacter(Tool.Parent):FindFirstChild("PlayerValues")
local Blocking = PlayerValues:WaitForChild("Blocking")
local Swinging = PlayerValues:WaitForChild("Swinging")
local PBWindow = PlayerValues:WaitForChild("PBWindow")
local Dashing = PlayerValues:WaitForChild("Dashing")
local Sprinting = PlayerValues:WaitForChild("Sprinting")
local WeaponEquipped = PlayerValues:WaitForChild("WeaponEquipped")
local Trail = Handle:WaitForChild("Trail")
local config = require(Tool:WaitForChild("Configuration"))
function isEquipped()
if Tool.Parent:FindFirstChild("Humanoid") then
return true else return false
end
end
Mouse.Button1Down:Connect(function()
if not isEquipped() then return end
Hit:FireServer()
if not SwingDB and not Dashing.Value and not Unequipping then
SwingDB = true
if Blocking then
BlockLogic(false, 0.1)
end
local SwingAnimationList = Animations:WaitForChild("Swings"):GetChildren()
local Selected = Animator:LoadAnimation(SwingAnimationList[SwingCycle])
if CurrentSwingAnimation then
CurrentSwingAnimation:Stop()
end
Selected:Play()
CurrentSwingAnimation = Selected
Swinging.Value = true -- Client First
local swingConfig = config["Swing" .. SwingCycle]
if swingConfig then
task.wait(swingConfig.AttackTime)
else
warn("Critical swing error. Mis-cycled swing. Unexplained.")
end
Swinging.Value = false -- Client First
SwingCycle += 1
task.wait(swingConfig.Cooldown)
if SwingCycle > 4 then SwingCycle = 1 end
SwingDB = false
end
end)
Mouse.Button2Down:Connect(function()
if not isEquipped() then return end
Block:FireServer(true, .1)
end)
Mouse.Button2Up:Connect(function()
Block:FireServer(false, .1)
end)
UserInputService.InputBegan:Connect(function(Input, GameProcessed)
if not isEquipped() or GameProcessed then return end
if Input.KeyCode == Enum.KeyCode.F then
Kick:FireServer()
if not KickDB and not SwingDB and not Dashing.Value then
SwingDB = true
KickDB = true
local KickTrack = Animator:LoadAnimation(Animations:WaitForChild("Specials"):WaitForChild("Kick"))
KickTrack:Play()
Humanoid.WalkSpeed = 26 -- Client First
task.wait(config.Kick.AttackTime)
Humanoid.WalkSpeed = 16 -- Client First
SwingDB = false
task.wait(config.Kick.Cooldown)
KickDB = false
end
end
end)
UserInputService.InputEnded:Connect(function(Input, GameProcessed)
if not isEquipped() or GameProcessed then return end
end)
local walk = Character:WaitForChild("Animate").walk
Tool.Equipped:Connect(function()
SheithMesh.Transparency = 1
Trail.Enabled = true
WeaponEquipped.Value = true -- Client First
KickDB = false
SwingDB = false
EquipAnimation = Animator:LoadAnimation(Animations:WaitForChild("Equips"):WaitForChild("Equip"))
EquipAnimation:Play()
if Sprinting.Value then -- Client First
Sprinting.Value = false
end
EquipAnimation.Ended:Wait()
Trail.Enabled = false
end)
Tool.Unequipped:Connect(function()
WeaponEquipped.Value = false -- Client First
Trail.Enabled = true
KickDB = true
SwingDB = true
if CurrentSwingAnimation then CurrentSwingAnimation:Stop() end
BlockLogic(false, .3)
UnequipAnimation = Animator:LoadAnimation(Animations:WaitForChild("Equips"):WaitForChild("Unequip"))
UnequipAnimation:Play()
UnequipSwordMesh.Transparency = 0
task.wait(1.2)
SheithMesh.Transparency = 0
UnequipSwordMesh.Transparency = 1
Trail.Enabled = false
end)
function BlockLogic(Boolean, TweenTime)
local BlockAnimation = Animations:WaitForChild("Specials"):WaitForChild("Block")
local Character = Player.Character
-- Store the animation in the character to persist across calls
if not Character:FindFirstChild("BlockingAnimation") then
local BlockingAnimation = Instance.new("ObjectValue")
BlockingAnimation.Name = "BlockingAnimation"
BlockingAnimation.Parent = Character
end
local BlockingAnimation = Character:FindFirstChild("BlockingAnimation")
if Boolean then
repeat task.wait() until not BlockDB
-- Stop the current swing/equip animation when the player starts blocking
if EquipAnimation then EquipAnimation:Stop() end
if Swinging.Value then -- Client First
Swinging.Changed:Wait()
end
-- If the block animation doesn't exist, load and play it
Blocking.Value = true
if not BlockingAnimation.Value then
local Track = Animator:LoadAnimation(BlockAnimation)
BlockingAnimation.Value = Track
Track:Play(TweenTime)
end
else
-- Stop the block animation if it's playing
Blocking.Value = false
if BlockingAnimation.Value then
local Track = BlockingAnimation.Value
Track:Stop(TweenTime)
BlockingAnimation.Value = nil -- Clear the reference to stop the animation
end
task.spawn(function()
if BlockDB then return end
BlockDB = true
task.wait(.15)
BlockDB = false
end)
end
end
Swinging.Changed:Connect(function(Bool) -- Client First
if Bool then
Trail.Enabled = true
else
Trail.Enabled = false
end
end)
Dashing.Changed:Connect(function(Bool)
if Bool then
if CurrentSwingAnimation then CurrentSwingAnimation:Stop(.15) end
BlockLogic(false, .1)
end
end)
The character is located in a folder in the workspace.