[SOLVED] Detect touching

Making this clear:
I’m not asking for any of you to write this script. I’m asking for simple directioning on:
How to detect if a player is constantly touching a part for 5 seconds efficiently.
I’ve scoured devforum, devhub, creator document and the cursed site that is stack overflow. There has been 0 helpful and efficient written ways. This is such a simple thing and I’ve tried multiple different ways.
Though inefficient there is:

while part.Touched do
	wait(1)
    if part.Touched then
       wait(1)
       if part.Touched then
          wait(1)
-- ECT ECT ECT until 5 seconds
      end
   end
end

This code would work but like I’ve stated, it’s inefficient and sloppy. There must be a better way?

1 Like

I believe you could start a countdown after Touched has fired, then wait until the countdown has ended or stop the countdown when TouchEnded has fired.

1 Like

So here’s what I’ve written so far and it works but it doesn’t detect when you move off the part. Meaning if you touch the part and walk off despite not waiting 5 seconds it’ll proceed anyway. Any fix to this script?

local flagbase = script.Parent
local proceed = false
--extra code
		if (player:IsInGroup(groups[1])) or player:IsInGroup(groups[2]) then
			print("Is in group")
			while flagbase.Touched do
				for i = 1,5,1 do
					wait(1)
					if flagbase.TouchEnded then
						break
					end
				end
				proceed = true
				while proceed ~= false do
					print("Next operation")
					flagbase.Highlight.FillColor = Color3.fromRGB(0, 255, 0) 
					flagbase.BillboardGui.Frame.ControlUI.Text = "XYZ"
					break
				end
				break
			end
		else
			for i = 1,5,1 do
				wait(1)
				if flagbase.TouchEnded then
					break
				end
			end
			proceed = true
			while proceed ~= false do
				print("Isn't in group")
				while flagbase.Touched do
				print("Next operation")
				flagbase.Highlight.FillColor = Color3.fromRGB(255, 0, 4)
				flagbase.BillboardGui.Frame.ControlUI.Text = "ABC"
					break
				end
				break
			end
		end
1 Like

Try making a variable called something like “touchingflagbase” then change it when the part is Touched or TouchEnded.

flagbase.Touched:Connect(function(hit)
--do ur checks if player or whatever
    touchingflagbase = true
end)

flagbase .TouchEnded:Connect(function(hit)
--do ur checks if player or whatever
    touchingflagbase = false
end)

If that doesn’t work theres also Region3 which I think is a bit more reliable seeing as it doesn’t fire multiple times.

1 Like

Made this real quick, didn’t test in studio so I apologize if there are any errors

local TouchedPlayers : table = {} -- if its a server script thats running this code, you'll need a table because multiple players could touch the part at the same time

part.Touched:Connect(function(hit)
      -- Check if its a player
       local Player = game.Players:GetPlayerFromCharacter(hit.Parent)

       table.insert(TouchingPlayer, Player.UserId) -- again, if this is a server script you'll need to do this

       task.delay(5, function()
              if table.find(TouchingPlayers, Player.UserId) then -- if its a local script you could just part.Touched
                     -- has been touching the part for 5 seconds
              end
       end)
end)

part.TouchedEnded:Connect(function(hit)
      -- Check if its a player
       local Player = game.Players:GetPlayerFromCharacter(hit.Parent)

       table.remove(TouchingPlayer, table.find(TouchingPlayer, Player.UserId))
end)
1 Like