Target still gets hit even outside of hitbox

Hello! I am currently writing a punching/hitbox script for a combat system, and I cannot figure out why the target still gets hit, even while the hitbox is not currently being touched by it.

I have tried to look through different sources and tried to look into the math part of it, but nothing I could find online matched and it doesn’t seem to be wrong to me.

Here is the server sided script (hitbox):

local rs = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")

local events = rs:WaitForChild("Events")
local hitboxEvent = events:WaitForChild("Hitbox")
local kbEvent = events:WaitForChild("Knockback")

function newHitbox(character, size, offset, damage, linger)
	local root = character:FindFirstChild("HumanoidRootPart") or character:FindFirstChild("Torso")
	if root == nil then
		print("root is nil")
		return
	end
	local weld = Instance.new("WeldConstraint", root)
	local hitbox = Instance.new("Part")
	weld.Part0 = root
	weld.Part1 = hitbox

	hitbox.CanCollide = false
	hitbox.CanQuery = false
	hitbox.Massless = true
	hitbox.Transparency = 0
	hitbox.Size = size
	hitbox.CFrame = root.CFrame + root.CFrame.LookVector * offset.X + Vector3.new(0, offset.Y)
	hitbox.Parent = character

	hitbox.Touched:Connect(function(hit)
		local humanoid = hit.Parent:FindFirstChild("Humanoid")
		if humanoid == nil then
			print("hit.Parent's humanoid is nil")
			return
		end
		for _, v in pairs(hitbox:GetChildren()) do
			if v:IsA("ObjectValue") then
				if v.Value == hit.Parent then
					kbEvent.OnServerEvent:Connect(function(targetCharacter)
						local targetRoot = hit.Parent:FindFirstChild("HumanoidRootPart")
						if targetRoot then
							local direction = (targetRoot.Position - root.Position).Unit
							local knockbackForce = 100
							targetRoot.Velocity = direction * knockbackForce
						end
					end)
					return
				end
			end
		end

		local hitCounter = Instance.new("ObjectValue", hitbox)
		hitCounter.Value = hit.Parent

		hit.Parent.Humanoid:TakeDamage(damage)
	end)

	game.Debris:AddItem(hitbox, linger)
end

hitboxEvent.OnServerEvent:Connect(function(plr, size, offset, damage, linger)
	local character = plr.Character
	if character then
		newHitbox(character, size, offset, damage, linger)
	end
end)

the client sided script pretty much just calls it during the animation.

Here is a video of what is going on:

Thank you!

1 Like

Hey. After setting the ObjectValues inside of the hitbox to “hit.Parent”, make them nil again or whatever their original value was.

for _, v in pairs(hitbox:GetChildren()) do
			if v:IsA("ObjectValue") then
				if v.Value == hit.Parent then
					kbEvent.OnServerEvent:Connect(function(targetCharacter)
						local targetRoot = hit.Parent:FindFirstChild("HumanoidRootPart")
						if targetRoot then
							local direction = (targetRoot.Position - root.Position).Unit
							local knockbackForce = 100
							targetRoot.Velocity = direction * knockbackForce
						end
                        v.Value = nil
					end)
					return
				end
			end
		end

You can also choose to use :Destroy(). If the ObjectValue is not set to nil, destroyed, or whatever the original value was, the .Touched function will register that the “targetRoot” still needs to be hit, since the ObjectValue’s value was not set to nil.

3 Likes

The rig is still being pushed – ill try using destroy and seeing what happens. Update: Neither of the solutions worked sorry, however on line 29-32, the target’s humanoid is registered as nil, printing “hit.Parent’s humanoid is nil” I believe this is because v.Value == hit.parent (target), so turning that value nil, the script does not see the humanoid for that line, but still registers that the target is touching the hitbox.

Sorry for my lateness. Is the for loop for area damage?

1 Like

The for loop is meant to detect any hrp inside the hitbox as they touch it. From what I understand of your question, it can be used to hit multiple targets in it, but the focus is just the hitbox in front of you. (as shown in the video)

If “TargetRoot” isn’t found inside the hitbox set it to “nil”