Block System Help

Basically, I’m trying to make a block system for a sword fighting game

If you swing from up, nothing can block it
if you swing from right to left, left to right can block it(and vice versa)
and if you swing from down, swinging from down can block it

Now, I’ve made a script in order to try achieve this, but issue is it just is extremely buggy(right to left blocking doesn’t work and vince versa) and I want to make blocks actually block so no damage is dealt to any of the players but the player who got blocked has damage dealt to him.

I see where the problem is, but I just can’t seem to fix it.
Can anybody help me fix this?

Server script(This script is a lil’ messy)

Script
local replicatedstorage = game:GetService("ReplicatedStorage")

local swing = replicatedstorage:WaitForChild("Swing")

local animid2 = "rbxassetid://118607943574615"

function animate(char, animid)
	local animationid = animid

	local humanoid = char.Humanoid
	local animator = humanoid.Animator

	local animation = Instance.new("Animation")
	animation.AnimationId = animationid

	animator:LoadAnimation(animation):Play()
	return animation
end

local directions = {
	["Right"] = function(plr)
		print(plr.Name)
		if plr.Character.Debounce.Value == false then
			plr.Character.Debounce.Value = true
			animate(plr.Character, "rbxassetid://89825808385671")
			local params = OverlapParams.new()
			params.FilterType = Enum.RaycastFilterType.Exclude
			local list = params.FilterDescendantsInstances
			for i,v in pairs(plr.Character:GetChildren()) do
				if v:IsA("BasePart") then
					table.insert(list, v)
				end
			end
			plr.Character.Humanoid.WalkSpeed = 8
			params.FilterDescendantsInstances = list
			local characters = {}
			for i,v in pairs(workspace:GetPartBoundsInBox(plr.Character.Hitbox.CFrame,plr.Character.Hitbox.Size, params)) do
				local humanoid = v.Parent:FindFirstChild("Humanoid")
				if humanoid and not characters[table.find(characters,v.Parent)]  then
					local damage = coroutine.create(function()
						task.wait(1)
						plr.Character.LastAttack.Value = ""
						local tag = Instance.new("StringValue")
						tag.Name = "tag"
						tag.Value = "Bottom"
						tag.Parent = humanoid.Parent
						local link = Instance.new("ObjectValue")
						link.Name = "Link"
						link.Value = plr.Character
						link.Parent = humanoid.Parent
						game.Debris:AddItem(tag,0.4)
						game.Debris:AddItem(link,1.4)
					end)
					coroutine.resume(damage)
					table.insert(characters,v.Parent)
				end
			end
			task.wait(.8)
			table.clear(characters)
			plr.Character.Humanoid.WalkSpeed = 16
			plr.Character.Debounce.Value = false
		end
	
	end,
	["Left"] = function(plr)
		print(plr.Name)
		if plr.Character.Debounce.Value == false then
			plr.Character.Debounce.Value = true
			animate(plr.Character, "rbxassetid://118607943574615")
			local params = OverlapParams.new()
			params.FilterType = Enum.RaycastFilterType.Exclude
			local list = params.FilterDescendantsInstances
			for i,v in pairs(plr.Character:GetChildren()) do
				if v:IsA("BasePart") then
					table.insert(list, v)
				end
			end
			plr.Character.Humanoid.WalkSpeed = 8
			params.FilterDescendantsInstances = list
			local characters = {}
			for i,v in pairs(workspace:GetPartBoundsInBox(plr.Character.Hitbox.CFrame,plr.Character.Hitbox.Size, params)) do
				local humanoid = v.Parent:FindFirstChild("Humanoid")
				if humanoid and not characters[table.find(characters,v.Parent)]  then
					local damage = coroutine.create(function()
						task.wait(1)
						plr.Character.LastAttack.Value = ""
						local tag = Instance.new("StringValue")
						tag.Name = "tag"
						tag.Value = "Left"
						tag.Parent = humanoid.Parent
						local link = Instance.new("ObjectValue")
						link.Name = "Link"
						link.Value = plr.Character
						link.Parent = humanoid.Parent
						game.Debris:AddItem(tag,0.4)
						game.Debris:AddItem(link,1.4)
					end)
					coroutine.resume(damage)
					table.insert(characters,v.Parent)
				end
			end
			task.wait(.8)
			table.clear(characters)
			plr.Character.Debounce.Value = false
			plr.Character.Humanoid.WalkSpeed = 16
		end
	end,
	["Top"] = function(plr)
		print(plr.Name)
		if plr.Character.Debounce.Value == false then
			plr.Character.Humanoid.WalkSpeed = 6
			plr.Character.LastAttack.Value = "Top"
			plr.Character.Debounce.Value = true
			animate(plr.Character, "rbxassetid://114267767707276")
			local params = OverlapParams.new()
			params.FilterType = Enum.RaycastFilterType.Exclude
			local list = params.FilterDescendantsInstances
			for i,v in pairs(plr.Character:GetChildren()) do
				if v:IsA("BasePart") then
					table.insert(list, v)
				end
			end
			params.FilterDescendantsInstances = list
			local characters = {}
			plr.Character.LastAttack.Value = "Top"
			for i,v in pairs(workspace:GetPartBoundsInBox(plr.Character.Hitbox.CFrame,plr.Character.Hitbox.Size, params)) do
				local humanoid = v.Parent:FindFirstChild("Humanoid")
				if humanoid and not characters[table.find(characters,v.Parent)]  then
					local damage = coroutine.create(function()
						task.wait(1)
						plr.Character.LastAttack.Value = ""
						local tag = Instance.new("StringValue")
						tag.Name = "tag"
						tag.Value = "Top"
						tag.Parent = humanoid.Parent
						local link = Instance.new("ObjectValue")
						link.Name = "Link"
						link.Value = plr.Character
						link.Parent = humanoid.Parent
						game.Debris:AddItem(tag,0.4)
						game.Debris:AddItem(link,1.4)
					end)
					coroutine.resume(damage)
					table.insert(characters,v.Parent)
				end
			end
			task.wait(1.4)
			table.clear(characters)
			plr.Character.Debounce.Value = false
			plr.Character.Humanoid.WalkSpeed = 16
		end
	end,
	["Bottom"] = function(plr)
		print(plr.Name)
		if plr.Character.Debounce.Value == false then
			plr.Character.Debounce.Value = true
			animate(plr.Character, "rbxassetid://97393020266500")
			local params = OverlapParams.new()
			params.FilterType = Enum.RaycastFilterType.Exclude
			local list = params.FilterDescendantsInstances
			for i,v in pairs(plr.Character:GetChildren()) do
				if v:IsA("BasePart") then
					table.insert(list, v)
				end
			end
			params.FilterDescendantsInstances = list
			local characters = {}
			for i,v in pairs(workspace:GetPartBoundsInBox(plr.Character.Hitbox.CFrame,plr.Character.Hitbox.Size, params)) do
				local humanoid = v.Parent:FindFirstChild("Humanoid")
				if humanoid and not characters[table.find(characters,v.Parent)]  then
					plr.Character.LastAttack.Value = "Bottom"
					local damage = coroutine.create(function()
						task.wait(1)
						plr.Character.LastAttack.Value = ""
						local tag = Instance.new("StringValue")
						tag.Name = "tag"
						tag.Value = "Bottom"
						tag.Parent = humanoid.Parent
						local link = Instance.new("ObjectValue")
						link.Name = "Link"
						link.Value = plr.Character
						link.Parent = humanoid.Parent
						game.Debris:AddItem(tag,0.4)
						game.Debris:AddItem(link,1.4)
					end)
					coroutine.resume(damage)
					table.insert(characters,v.Parent)
				end
			end
			plr.Character.Humanoid.WalkSpeed = 11
			task.wait(.4)
			--plr.Character.LastAttack.Value = ""
			table.clear(characters)
			plr.Character.Humanoid.WalkSpeed = 16
			plr.Character.Debounce.Value = false
		end
	end,
}

swing.OnServerEvent:Connect(function(plr,directionstring)
	local direction = directions[directionstring]
	if direction then
		print("sdfg")
		coroutine.wrap(direction)(plr)
	end
end)

Script in the character

Script
local char = script.Parent

local tags ={
	["Bottom"] = {
		15,
		"Bottom"
	},
	["Right"] = {
		35,
		"Left"
	},
	["Left"] = {
		35,
		"Right"
	},
	["Top"] = {
		65,
		"NoCounter"
	}
}

char.ChildAdded:Connect(function(child)
	if child.Name == "tag" then
		local tag = tags[child.Value]
		if char.LastAttack.Value == tag[2] then
			local coroutine1 = coroutine.create(function()
				task.wait(.2)
				char.Link.Value.Humanoid.WalkSpeed = 11
				char.Link.Value.Debounce.Value = true
				task.wait(1)
				char.Link.Value.Humanoid.WalkSpeed = 16
				char.Link.Value.Debounce.Value = false
			end)
			coroutine.resume(coroutine1)
		else
			char.Humanoid.Health -= tag[1]
		end
	end
end)

Help me please guys l still can’t figure this out

This is… really messy code. And I meant that in the sense it’s very difficult to understand what the code is doing and through what methods. There’s

What I’d do is have a table for each attack direction, and when the swing function is called, it takes the attack direction’s variables (such as time, endlag, damage, animation, ect). This would save the need for a new function per attack direction.

For damage and blocking I would use a module script to store the current block direction, as well as the general damage function. If the target is blocking, then additional checks are performed when hit to see if the condition are right to actually block the attack. I have a guide here for module scripts such as these.

1 Like

Making it into a table helped me immensely and helped me find the solution to making it block as the script was organized, thanks