[Closed] How do I efficiently detect if a player is touching a part?

I want to be able to check if a player is touching a part and when they are not, to set a value to false. Here is the code that I am starting with:

for i, rail in pairs(rails:GetChildren()) do
	rail.Touched:Connect(function(part)
		if part.Parent:FindFirstChild("Humanoid") then
			local player = game.Players:GetPlayerFromCharacter(part.Parent)
			if player ~= nil then
				bodyPartTouching[player.Name] += 1
				print(player.Name.." is touching rail with "..bodyPartTouching[player.Name].." body parts")
				if player.IsTouchingRail.Value == false then
					player.IsTouchingRail.Value = true
				end
			end
		end
	end)
	rail.TouchEnded:Connect(function(part)
		if part.Parent:FindFirstChild("Humanoid") then
			local player = game.Players:GetPlayerFromCharacter(part.Parent)
			if player ~= nil then
				bodyPartTouching[player.Name] -= 1
				if bodyPartTouching[player.Name] == 0 then
					player.IsTouchingRail.Value = false
					print("player has stopped touching part")
				end
			end
		end
	end)
end
This is only a snippet, here is the full script
local rails = game.Workspace:WaitForChild("Rails")
local bodyPartTouching = {}

setmetatable(bodyPartTouching,
	{__index = function() return 0 end}
)

game.Players.PlayerAdded:Connect(function(plr)
	local isTouchingRail = Instance.new("BoolValue")
	isTouchingRail.Parent = plr
	isTouchingRail.Name = "IsTouchingRail"
	isTouchingRail.Value = false
end)

for i, rail in pairs(rails:GetChildren()) do
	rail.Touched:Connect(function(part)
		if part.Parent:FindFirstChild("Humanoid") then
			local player = game.Players:GetPlayerFromCharacter(part.Parent)
			if player ~= nil then
				bodyPartTouching[player.Name] += 1
				print(player.Name.." is touching rail with "..bodyPartTouching[player.Name].." body parts")
				if player.IsTouchingRail.Value == false then
					player.IsTouchingRail.Value = true
				end
			end
		end
	end)
	rail.TouchEnded:Connect(function(part)
		if part.Parent:FindFirstChild("Humanoid") then
			local player = game.Players:GetPlayerFromCharacter(part.Parent)
			if player ~= nil then
				bodyPartTouching[player.Name] -= 1
				if bodyPartTouching[player.Name] == 0 then
					player.IsTouchingRail.Value = false
					print("player has stopped touching part")
				end
			end
		end
	end)
end

Now, it works when a player touches it from the side of the part, but when I stand on top and walk off I don’t see “player has stopped touching part” in the output. How do I fix this? What I really want is a script that knows when a player is touching or has stopped touching a part and to set a value to true or false.

PS

On a similar topic I posted yesterday, someone told me I could use :GetTouchingParts the problem with this is processing the table, the script would have to take all these steps to make it work:

  1. Determine who’s parts are who’s and if they belong to a player and if so, add that player to an “is touching table”
  2. Then set all those player’s values to true, and all the players who are not touching the part to false not to false

This would be a lot data to process and may not even work because of runtime especially with a lot of players.

4 Likes

To detect if a player is touching a specific part I use:

script.Parent.Touched:Connect(function(touch)
	if touch.Parent:FindFirstChildOfClass("Humanoid") then
		print(touch.Parent.Name)
	end
end)

and to know when to stop playing a certain part I use:

script.Parent.TouchEnded:Connect(function()
	print("Touched endend")
end)
12 Likes