Touched event only detects an initial touch, but how would i continously detect a touch

I want to make a punch system that can detect when the player is in the hitbox zone. The problem is that .Touched event only detects an initial touch rather than when the user is in the hitbox zone. Therefore the function only runs once. So im wondering if there is any alterative to .Touched that checks continuously when the user is in the zone.

My code:

fists.Touched:Connect(function(hit)
	print("hit")
	if swinging == true then
		if hit.Parent:FindFirstChild("Humanoid") then
			local enemyhum = hit.Parent:FindFirstChild("Humanoid")

			swinging = false

			senddamage:FireServer(enemyhum)

			if comboNum == 1 then
				sendknock:FireServer(hit)
			end
		end
	end
end)

You could use a distance thing, it would be very inefficient but if you want I could show you how.

You can’t … but you can tell when it stops being held down and that’s all you need.

local UserInputService = game:GetService("UserInputService")
local punching = false

UserInputService.InputBegan:Connect(function(input)
    if input.KeyCode == Enum.KeyCode.F then
        punching = true
        while punching do
            senddamage:FireServer()
            if comboNum == 1 then
                sendknock:FireServer()
            end
            task.wait(0.1)
        end
    end
end)

UserInputService.InputEnded:Connect(function(input)
    if input.KeyCode == Enum.KeyCode.F then
        punching = false
    end
end)

Just a mock-up will need some love.
That’s about as cut down as I can get it … This is most likely too fast … task.wait(0.1)
You’ll need to play around with it.

the “punching” is a variable that is set to true when the player is in the punching motion. Not when the player is holding down. My mistake for making it very vague :slightly_smiling_face:

Ya I’m not posting actual code here … this is more of a direction.
InputBegan … InputEnded. I’m sure you can figure this out from here.

whats the distance thing? I havent heard of that

As I said this is very inefficient, but you take all the players and if one has a distance to you (lets say 10) then you could do your code,

Here is an example:

local uis = game:GetService("UserInputService")

uis.InputBegan:Connect(function(i,g)
	if i.KeyCode == Enum.KeyCode.F and g == false then
		for _, player in pairs(workspace:GetChildren()) do
			local humanoid = player:FindFirstChildWhichIsA("Humanoid")
			if player:IsA("Model") and humanoid and player ~= script.Parent.Parent.Character then
				local distance = (player.PrimaryPart.Position - script.Parent.Parent.Character.PrimaryPart.Position).Magnitude
				if distance <= 10 then
					print(player.Name)
					-- put your code here
				end
			end
		end
	end
end)

Not sure why this is better than just using normal Touched, also the script does AOE

use spatial query or raycast v4 for your hitbox system. I recommend spatial query since its simple. .touched is unreliable and should be avoided at all costs

I found the solution!
After an hour of additional digging, I found a solution.
This is the script I used:

rs.Heartbeat:Connect(function()
	for i, v in pairs(game.Workspace:GetPartsInPart(fists)) do
		if v.Name == "Torso" then
			local enemyhum = v.Parent:FindFirstChild("Humanoid")
			if swinging == true and enemyhum ~= hum then

				swinging = false

				senddamage:FireServer(enemyhum)
				print("damage sent")

				if comboNum == 1 then
					sendknock:FireServer(enemyhum)
				end
			end
		end
	end
end)

Thanks to everyone who helped :slightly_smiling_face:

1 Like