Script is too slow pls help

I am trying to make a sword combat script and i wanted to change the value isAttacking to true in server script so that another server script can see the changes the problem is that it’s too slow . If time correctly the player can do two attacks in one

here’s what it should do :

Here’s the problem :

Here’s the local script

local player = game.Players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local humanoid = character:WaitForChild("Humanoid")

local isBlocking = player:WaitForChild("valueFolder"):WaitForChild("isBlocking")
local isAttacking = player:WaitForChild("valueFolder"):WaitForChild("isAttacking")
local isStunned = player:WaitForChild("valueFolder"):WaitForChild("isStunned")

local replicatedStorage = game:GetService("ReplicatedStorage")
local M1SwordEvent = replicatedStorage.AbilityEvents.SwordEvents:WaitForChild("M1SwordEvent")
local sprintEvent = replicatedStorage.AbilityEvents.Others:WaitForChild("SprintEvent")

local slash1 = humanoid:LoadAnimation(script:WaitForChild("Slash1"))
local slash2 = humanoid:LoadAnimation(script:WaitForChild("Slash2"))
local slash3 = humanoid:LoadAnimation(script:WaitForChild("Slash3"))

local UIS = game:GetService("UserInputService")

local count = 1

local lastM1 = 0

local debounce = false

local function SpawnHitBox(size,cframe,ignore) -- Creates Hibox
	local hitBox = Instance.new("Part",workspace)
	hitBox.Anchored = true
	hitBox.Name = "HitBox"
	hitBox.Transparency = .5
	hitBox.BrickColor = BrickColor.new("Really red")
	hitBox.Material = Enum.Material.ForceField
	hitBox.CanCollide = false
	hitBox.CanQuery = false
	hitBox.Size = size
	hitBox.CastShadow = false
	hitBox.CFrame = cframe

	local con 
	con = hitBox.Touched:Connect(function()
		con:Disconnect()
	end)

	local target = {}
	for i , v in pairs(hitBox:GetTouchingParts()) do
		if v.Parent:FindFirstChild("Humanoid") and table.find(ignore,v.Parent) == nil then
			if table.find(target,v.Parent.PrimaryPart) == nil then
				table.insert(target,v.Parent.PrimaryPart)
			end 
		end
	end

	--hitBox:Destroy()
	if #target ~= nil then
		return target
	else
		return nil
	end
end

UIS.InputBegan:Connect(function(input , gpe)
	if gpe then return end
	
	if os.time() - lastM1 > 3 then
		count = 1
	end
	
	if input.UserInputType == Enum.UserInputType.MouseButton1 and humanoid.Health > 0 and count == 1 and character:FindFirstChild("Sword") and isAttacking.Value == false and isBlocking.Value == false and isStunned.Value == false and debounce == false then -- First attack
		if slash3.IsPlaying == true then
			slash3:Stop()
		end
		
		lastM1 = os.time()

		debounce = true
		
		slash1:Play()
		
		local hitTarget = SpawnHitBox(Vector3.new(5.5,5,5),character:WaitForChild("HumanoidRootPart").CFrame * CFrame.new(0,0,-3),{character})
		M1SwordEvent:FireServer(hitTarget,0.4)
		
		sprintEvent:FireServer("StopSprint",10)

		task.wait(0.4)

		debounce = false
		
		count += 1
	elseif input.UserInputType == Enum.UserInputType.MouseButton1 and humanoid.Health > 0 and count == 2 and character:FindFirstChild("Sword") and isAttacking.Value == false and isBlocking.Value == false and isStunned.Value == false and debounce == false then -- Second Attack
		if slash1.IsPlaying == true then
			slash1:Stop()
		end
		
		debounce = true

		lastM1 = os.time()
		
		slash2:Play()
		
		local hitTarget = SpawnHitBox(Vector3.new(5.5,5,5),character:WaitForChild("HumanoidRootPart").CFrame * CFrame.new(0,0,-3),{character})
		M1SwordEvent:FireServer(hitTarget,0.4)
		
		sprintEvent:FireServer("StopSprint",10)
		
		task.wait(0.4)

		debounce = false
		
		count += 1
	elseif input.UserInputType == Enum.UserInputType.MouseButton1 and humanoid.Health > 0 and count == 3 and character:FindFirstChild("Sword") and isAttacking.Value == false and isBlocking.Value == false and isStunned.Value == false and debounce == false then -- Third Attack
		if slash2.IsPlaying == true then
			slash2:Stop()
		end
		
		debounce = true

		lastM1 = os.time()
		
		slash3:Play()
		
		local hitTarget = SpawnHitBox(Vector3.new(5.5,5,5),character:WaitForChild("HumanoidRootPart").CFrame * CFrame.new(0,0,-3),{character})
		M1SwordEvent:FireServer(hitTarget,1)
		
		sprintEvent:FireServer("StopSprint",4)

		slash3.Stopped:Wait()
		humanoid.WalkSpeed = 10

		task.wait(1)
		
		debounce = false
		
		count = 1
	end
end)

Here’s the server script

local replicatedStorage = game:GetService("ReplicatedStorage")
local M1SwordEvent = replicatedStorage.AbilityEvents.SwordEvents:WaitForChild("M1SwordEvent")

local Debris = game:GetService("Debris")

local play = true

M1SwordEvent.OnServerEvent:Connect(function(player,hitTarget,Time)
	local character = player.Character or player.CharacterAdded:Wait()
	local humanoid = character:WaitForChild("Humanoid") 

	local damageMultiplier = player:WaitForChild("valueFolder"):WaitForChild("DamageMultiplier")
	local isAttacking = player:WaitForChild("valueFolder"):WaitForChild("isAttacking")
	
	isAttacking.Value = true
	
	task.delay(Time,function()
		isAttacking.Value = false
	end)
	
	for i , targetPrimaryPart in pairs(hitTarget) do -- Loop through all targets
		local characterTarget = targetPrimaryPart.Parent
		local playerTarget = game.Players:GetPlayerFromCharacter(characterTarget) 
		local humanoidTarget = characterTarget:WaitForChild("Humanoid")
		local humanoidRootPartTarget = characterTarget:WaitForChild("HumanoidRootPart")
		
		local anim = {
			humanoidTarget:WaitForChild("Animator"):LoadAnimation(script:WaitForChild("HitAnim1")),
			humanoidTarget:WaitForChild("Animator"):LoadAnimation(script:WaitForChild("HitAnim2"))
		}
		
		local function effect(effect,emitCount) -- Just Some Effects
			local hitParticle = effect
			hitParticle.Parent = targetPrimaryPart.Parent.Torso

			hitParticle:Emit(emitCount)

			task.delay(.5,function()
				hitParticle:Destroy()
			end)
		end

		if playerTarget and playerTarget:WaitForChild("valueFolder"):WaitForChild("isBlocking").Value == true then -- if he blocks
			character:FindFirstChild("Sword"):FindFirstChild("BlockSound"):Play()
			
			effect(game.ReplicatedStorage.Fx.BlockEffect:Clone(),30)
		elseif humanoidTarget.Health > 0 then
			if humanoid:FindFirstChild("Tag") then
				if humanoid:FindFirstChild("Tag").Value ~= character then
					local tag = Instance.new("ObjectValue",humanoidTarget)
					tag.Name = "Tag"
					tag.Value = character

					Debris:AddItem(tag,2)
				end
			else
				local tag = Instance.new("ObjectValue",humanoidTarget)
				tag.Name = "Tag"
				tag.Value = character

				Debris:AddItem(tag,2)
			end
			
			characterTarget.Humanoid:TakeDamage(10 * damageMultiplier.Value)

			character:FindFirstChild("Sword"):FindFirstChild("Slash"):Play() -- This is a sound
			
			for i , v in pairs(humanoidTarget:GetPlayingAnimationTracks()) do
				v:Stop()
			end
			
			local hitAnim = anim[math.random(1,2)]
			hitAnim:Play()
			
			if playerTarget then
				local isStunnedTarget = playerTarget:WaitForChild("valueFolder"):WaitForChild("isStunned")

				isStunnedTarget.Value = true

				hitAnim.Stopped:Connect(function()
					isStunnedTarget.Value = false
				end)
			end
			
			effect(replicatedStorage.Fx.HitParticle:Clone(),30)	
		end
	end
end)
1 Like

Instead of using a value, you could check if the animation is playing or not using Animator:GetPlayingAnimationTracks() additionally, you could try using CustomAttributes as those might be faster than updating values. If these solutions don’t work, you could merge the two scripts together and share a debounce variable.

2 Likes

WOW! Attributes are much much faster! Thanks man you helped me a lot

2 Likes

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.