-- Defining all variables and default settings local Player = game:GetService("Players").LocalPlayer local Character = Player.Character local UserInputService = game:GetService("UserInputService") local RunService = game:GetService("RunService") local ReplicatedStorage = game:GetService("ReplicatedStorage") local Players = game:GetService("Players") local ValuesFolder = Character:WaitForChild("ValuesFolder") local Humanoid = Character:WaitForChild("Humanoid") local HumanoidRootPart = Character:WaitForChild("HumanoidRootPart") local GlobalValues = workspace.GlobalValues local DefaultWalkSpeed = GlobalValues.DefaultWalkSpeed.Value local PunchExtendTime = GlobalValues.PunchExtendTime.Value local RemoteEvents = ReplicatedStorage.RemoteEvents local Models = ReplicatedStorage.Models local PunchEvent = RemoteEvents.PunchEvent local AbilityEvent = RemoteEvents.AbilityEvent local BlockEvent = RemoteEvents.BlockEvent local BlockHealth = ValuesFolder.BlockHealth local BlockValue = ValuesFolder.BlockValue local StunValue = ValuesFolder.StunValue local PunchValue = ValuesFolder.PunchValue local QuirkValue = ValuesFolder.QuirkValue local ShieldPart = Models.ShieldPart:Clone() ShieldPart.Parent = Character ShieldPart.Anchored = true ShieldPart.CanCollide = false local Punch = false local ComboChange = false local PunchCooldown = false local BlockCooldown = false local PunchCooldownTime = 1.5 local BlockCooldownTime = 1 local CurrentCombo = 1 local EEnabled = false local ECooldown = false local ECooldownTime = 3 -- Defining animations local PunchAnim1 = Instance.new("Animation") local PunchAnim2 = Instance.new("Animation") local PunchAnim3 = Instance.new('Animation') local PunchAnim4 = Instance.new("Animation") local BlockAnim = Instance.new("Animation") PunchAnim1.AnimationId = "rbxassetid://8424753955" PunchAnim2.AnimationId = "rbxassetid://8558034150" PunchAnim3.AnimationId = "rbxassetid://8558036858" PunchAnim4.AnimationId = "rbxassetid://8704215101" BlockAnim.AnimationId = "rbxassetid://9332282060" local PunchAnimation1 = Humanoid:LoadAnimation(PunchAnim1) local PunchAnimation2 = Humanoid:LoadAnimation(PunchAnim2) local PunchAnimation3 = Humanoid:LoadAnimation(PunchAnim3) local PunchAnimation4 = Humanoid:LoadAnimation(PunchAnim4) local BlockAnimation = Humanoid:LoadAnimation(BlockAnim) local Animations = {PunchAnimation1, PunchAnimation2, PunchAnimation3, PunchAnimation4, BlockAnimation} local PunchAnimations = { [1] = PunchAnimation1, [2] = PunchAnimation2, [3] = PunchAnimation3, [4] = PunchAnimation4 } Humanoid.WalkSpeed = DefaultWalkSpeed Humanoid:SetStateEnabled(Enum.HumanoidStateType.Climbing, false) -- Defining all functions local function ShiftLockFunction(Bool) -- Currently not in use but useful in the future if Bool then Humanoid.CameraOffset = Vector3.new(1.75, 0, 0) Humanoid.AutoRotate = false UserInputService.MouseIconEnabled = false -- Hiding the cursor RunService:BindToRenderStep("ShiftLock", Enum.RenderPriority.Character.Value, function() UserInputService.MouseBehavior = Enum.MouseBehavior.LockCenter local XAxis, YAxis = workspace.CurrentCamera.CFrame.Rotation:ToEulerAnglesYXZ() HumanoidRootPart.CFrame = CFrame.new(HumanoidRootPart.Position) * CFrame.Angles(0, YAxis, 0) -- Rotating the HumanoidRootPart with the camera angle end) else Humanoid.CameraOffset = Vector3.new(0,0,0) RunService:UnbindFromRenderStep("ShiftLock") -- Stopping the loop UserInputService.MouseIconEnabled = true UserInputService.MouseBehavior = Enum.MouseBehavior.Default Humanoid.AutoRotate = true end end local function StopAllAnimationsFunction() for i,v in Animations do -- Loops through all of the animations and forces them to stop v:Stop() end end local function PunchCooldownFunction() CurrentCombo = 1 PunchCooldown = true PunchAnimation1:Stop() PunchAnimation2:Stop() PunchAnimation3:Stop() task.delay(PunchCooldownTime, function() PunchCooldown = false end) end local function GetPlayersFromHitboxFunction(Part) local EnemiesTable = {} for i,v in workspace:GetPartsInPart(Part) do local EnemiesCharacter = v.Parent if not EnemiesCharacter or EnemiesCharacter == Character or not EnemiesCharacter:FindFirstChild("Humanoid") then continue end -- Checks for all parts in the Hitbox if their parent has a Huamnoid and if their parent isn't a descendant of our Chracter. If so, the script continues. if table.find(EnemiesTable, EnemiesCharacter) then continue else table.insert(EnemiesTable, EnemiesCharacter) end end return EnemiesTable end RunService.Stepped:Connect(function() -- Making the Shield always position at the front of the player if BlockValue.Value and BlockHealth.Value > 0 then -- Check ShieldPart.CFrame = HumanoidRootPart.CFrame + HumanoidRootPart.CFrame.LookVector * 2 elseif not BlockValue.Value and BlockHealth.Value <= 0 then BlockEvent:FireServer(false) BlockAnimation:Stop() end -- Changing the visibility and color depending if the player is blocking or not for i,v in ShieldPart:GetChildren() do if v:IsA("Decal") then v.Color3 = Color3.fromRGB(255, BlockHealth.Value * 2.55, BlockHealth.Value * 2.55) if BlockValue.Value then v.Transparency = 0.5 else v.Transparency = 1 end end end -- Hiding all server-side shields for i1,v1 in workspace:GetDescendants() do if v1.Name == "ShieldPartServer" and v1.Parent == Character then for i2,v2 in v1:GetChildren() do if v2:IsA("Decal") then v2.Transparency = 1 end end end end end) UserInputService.InputBegan:Connect(function(Key, GameProcessed) -- Making sure the player isn't typing if GameProcessed then return end -- Checking for inputs like pressing F or clicking the left mouse button -- Using some premade functions, playing animations and setting blocking values if Key.KeyCode == Enum.KeyCode.F then if BlockHealth.Value <= 20 or Punch or BlockCooldown then return end StopAllAnimationsFunction() -- Stopping all the animations so they don't Humanoid.WalkSpeed = 5 BlockCooldown = true delay(BlockCooldownTime, function() -- Cooldown so the player can't keep blocking and unblocking BlockCooldown = false end) BlockEvent:FireServer(true) BlockAnimation:Play() end -- Checking if the player is blocking or not if BlockValue.Value then return end -- Creatng hitboxes, setting cooldowns, and playing animations for punching if Key.UserInputType == Enum.UserInputType.MouseButton1 then if Punch == false and PunchCooldown == false and PunchValue.Value == true then Punch = true local Part = Instance.new("Part") local EnemiesTable = {} StopAllAnimationsFunction() -- Making the Hitbox Part Part.Anchored = true Part.CanCollide = false Part.CFrame = HumanoidRootPart.CFrame + HumanoidRootPart.CFrame.LookVector * 3 Part.Size = Vector3.new(6, 6, 6) Part.Parent = workspace Part.Transparency = 1 PunchAnimations[CurrentCombo]:Play() -- A trick I came up with to optimize playing the animations - instead of multiple if statements, I just use the Current Combo number and the Punch Animations table task.spawn(function() if CurrentCombo ~= 4 then task.spawn(function() local Animation = PunchAnimations[CurrentCombo] task.wait(Animation.Length * 0.9) Animation:AdjustSpeed(0) -- Stopping the animation and wait for the next punch to come in end) ComboChange = true -- Letting know that the combo has changed task.wait(0.05) ComboChange = false task.spawn(function() local PreviousUnix = tick() -- Getting the Previous Unix repeat task.wait() until tick() - PreviousUnix > PunchExtendTime or ComboChange == true -- Waiting for either the player to wait too long or for a next combo change if tick() - PreviousUnix > PunchExtendTime then -- If the player waits too long the combo gets resetted PunchCooldownFunction() elseif ComboChange == true then return end end) end end) EnemiesTable = GetPlayersFromHitboxFunction(Part, EnemiesTable) Part:Destroy() local ClosestEnemy = nil -- Looping through the Enemies Table and getting the closest one for i,v in EnemiesTable do if ClosestEnemy == nil or (v.HumanoidRootPart.Position - ClosestEnemy.HumanoidRootPart.Position).Magnitude >= (HumanoidRootPart.Position - v.HumanoidRootPart.Position).Magnitude then -- Getting the position difference between the player and the enemies to get the closest one ClosestEnemy = v end end if ClosestEnemy ~= nil then -- Making sure if there's a enemy to attack in reach PunchEvent:FireServer(Character, ClosestEnemy, CurrentCombo) end if CurrentCombo == 4 then -- If it was the last combo attack, there goes a cooldown PunchCooldownFunction() end CurrentCombo += 1 local PreviousUnix = tick() task.wait(PunchAnimations[CurrentCombo].Length * 0.55 + 0.05) -- Making a debounce wait so the player can't do 4 attacks at once within a blink of an eye Punch = false end end end) -- Cancelling blocking if the F button is not pressed anymore UserInputService.InputEnded:Connect(function(Key, GameProcessed) if GameProcessed then return end if Key.KeyCode == Enum.KeyCode.F then BlockEvent:FireServer(false) -- Sending a Remote Event to the server to change some variables and disable the server-side shield BlockAnimation:Stop() -- Stopping the animation Humanoid.WalkSpeed = DefaultWalkSpeed end end)