Making An Automatic Combat Blocking System

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
2 Likes

Thank you so much for helping me so many times. Also I want to know is my code clear enough? Is it optimized?

tbh I think it is bad that your entire code is client sided, as exploiters can easily use the remote functions.

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.

There are other ways to do it but ig yours is fine.

Can I ask you about some ways?

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?

1 Like

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.

It’s kind of clean but you can definitely remove many ifs there:

if Typing == false and input.KeyCode == Enum.KeyCode.F and Humanoid.Health > 0 then

You could do this instead of putting a single check in different lines. That’s just my way tho, it’s your complete choice!

1 Like