Hey guys. Recently, I’ve been working on a combat blocking system and found that if I try to block when my character is stunned (When it can’t block), the block doesn’t work even if I still hold the key, it only works if I press the key again. So I want to make a blocking system, that will wait the character to be not stunned, if the key is still being held down, and fire the function. I’ve tried this code:
local Player = game.Players.LocalPlayer
local UIS = game:GetService("UserInputService")
local BlockingAnim = script:WaitForChild("BlockingAnim")
local CD = 1
local debounce = false
local Animation = Humanoid:LoadAnimation(BlockingAnim)
local BlockingEvent = game.ReplicatedStorage.BlockingEvent
UIS.InputBegan:Connect(function(input,Typing)
if not Typing then
if Humanoid.Health > 0 then
if input.KeyCode == Enum.KeyCode.F then
if not Character:FindFirstChild("Guardbreak") and not Character:FindFirstChild("Stun") and not Character:FindFirstChild("eStun") and debounce == false then -- Checks if the character is not stunned and if it is so, fires the function
debounce = true
BlockingEvent:FireServer()
Animation:Play()
wait(CD)
debounce = false
else -- If the character is stunned
while wait() do
if UIS:IsKeyDown(Enum.KeyCode.F) then -- Checks if the key is still being held
if not Character:FindFirstChild("Guardbreak") and not Character:FindFirstChild("Stun") and not Character:FindFirstChild("eStun") and debounce == false then -- Checks if the character is not stunned and if it so, fires the function
debounce = true
BlockingEvent:FireServer()
Character:WaitForChild("Run").Value = false
Animation:Play()
wait(CD)
debounce = false
break -- The function is fired, breaks the loop
end
else -- The key is not being held anymore
break -- Breaks the loop
end
end
end
end
end
end
end)
This code works, but it’s a bit laggy, is there a way to optimize it, or should I make a RenderStepped event instead of a while loop? Thanks in advance.
RenderStepped is always the solution if you want an almost immediate response, so yeah you could use it. You can replace:
while wait() do -- (Which I recommend to transform into task.wait() to update the code to the new task library)
with
while RunService.RenderStepped:Wait() do
And by the way you can directly move the check for holding the F with the other if statement. It doesn’t change anything, but makes your code cleaner as you’d remove 4 lines.
if UIS:IsKeyDown(Enum.KeyCode.F) and not Character:FindFirstChild("Guardbreak") and not Character:FindFirstChild("Stun") and not Character:FindFirstChild("eStun") and debounce == false then
I’m using UserInputService here, that’s why the code is client-sided, the rest of the code, like making a blocking value true and effects are server-sided, also there are values that can’t be changed from the server, because it’s needed to fire the event, this process is too slow in some occasions.
I don’t have time to explain but like every time someone presses the key, fire a function that tells the server they pressed it, then calculate the debounce and other stuff on the server.
If I have a stun and debounce check on the client side, for not firing the event for no reason every time, and I have these checks on the server side to prevent exploiting, is that alright?
He literally needs to have it on the client if he wants to do what he has done here. Plus, he can put checks both on the client and on the server, no need to move every check on the server. If he doesn’t add checks on the client then it would just become remote-spamming when holding F.