Seems like equiping a tool triggers a part's touch ended event

Hey so I am making an area loader for a game I’m developing and it seems whenever I equip a tool the part.TouchEnded event gets triggered and then part.Touch right after it

If anyone knows a fix for this please let me know, this is the script I have below

server script

local Areas = workspace:FindFirstChild("AREA_LOADER")
local Players = game:GetService("Players")
local Load = game:GetService("ReplicatedStorage").AREA_LOADER.Load
local Deload = game:GetService("ReplicatedStorage").AREA_LOADER.Deload

for _, child in ipairs(Areas:GetChildren()) do
	local trigger = child:FindFirstChild("LoadTrigger")
	local parts = child:FindFirstChild("Parts")
	if trigger and parts then
		trigger.Touched:Connect(function(partTouched)
			if partTouched.Parent:FindFirstChild("Humanoid") then
				if partTouched.Name == "HumanoidRootPart" then
					local player = Players:FindFirstChild(partTouched.Parent.Name)
					if player then
						Load:FireClient(player, child.Name)
					end
				end
			end
		end)

		trigger.TouchEnded:Connect(function(partTouched)
			if partTouched.Parent:FindFirstChild("Humanoid") then
				if partTouched.Name == "HumanoidRootPart" then
					local player = Players:FindFirstChild(partTouched.Parent.Name)
					if player then
						Deload:FireClient(player, child.Name)
					end
				end
			end
		end)
	end
end

What is the reason for using the touchEnded event in this case? Does unequip event not work? Maybe add a test case for if not the player that owns the tool? aka if not tool.backpack.Parent?

I’ve changed it to detect if your actually still within the cords of the trigger and it seems to work, added a bit of clearance so it still unloads properly. If anyone comes up with this issue again this is the solution

local Areas = workspace:FindFirstChild("AREA_LOADER")
local Players = game:GetService("Players")
local Load = game:GetService("ReplicatedStorage").AREA_LOADER.Load
local Deload = game:GetService("ReplicatedStorage").AREA_LOADER.Deload

for _, child in ipairs(Areas:GetChildren()) do
	local trigger = child:FindFirstChild("LoadTrigger")
	local parts = child:FindFirstChild("Parts")
	if trigger and parts then
		trigger.Touched:Connect(function(partTouched)
			if partTouched.Parent:FindFirstChild("Humanoid") then
				if partTouched.Name == "HumanoidRootPart" then
					local player = Players:FindFirstChild(partTouched.Parent.Name)
					if player then
						Load:FireClient(player, child.Name)
					end
				end
			end
		end)

		trigger.TouchEnded:Connect(function(partTouched : Instance)
			if partTouched.Parent:FindFirstChild("Humanoid") then
				print(`Part: {partTouched.Name} Left Trigger`)
				if partTouched.Name == "HumanoidRootPart" then
					if not isPositionInsidePart(trigger, partTouched.Position) then
						local player = Players:FindFirstChild(partTouched.Parent.Name)
						if player then
							Deload:FireClient(player, child.Name)
						end
					end
				end
			end
		end)
	end
end

function isPositionInsidePart(basePart, testPosition, clearance)
	clearance = clearance or 1 

	if basePart and basePart:IsA("BasePart") then
		local partSize = basePart.Size
		local partPosition = basePart.Position

		local halfExtentsWithClearance = (partSize - Vector3.new(clearance, clearance, clearance)) / 2

		local minBoundsWithClearance = partPosition - halfExtentsWithClearance
		local maxBoundsWithClearance = partPosition + halfExtentsWithClearance

		local isInsideX = testPosition.X >= minBoundsWithClearance.X and testPosition.X <= maxBoundsWithClearance.X
		local isInsideY = testPosition.Y >= minBoundsWithClearance.Y and testPosition.Y <= maxBoundsWithClearance.Y
		local isInsideZ = testPosition.Z >= minBoundsWithClearance.Z and testPosition.Z <= maxBoundsWithClearance.Z

		return isInsideX and isInsideY and isInsideZ
	else
		return false
	end
end

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.