Server Touched Event doesn't fire if part is deleted on client?


The big wall is deleted on the client and the part welded to my character has a touched event connected to it. When I walk through it the touched event doesn’t fire. Although if I have an NPC which is walking into the wall, then the touched event does fire when i walk into it. Can someone explain this behavior?

Even I had this issue a couple months ago, sadly I figured out that the TouchTransmitters are heavily client-based, meaning if the client deletes it, it doesn’t fire the Touched event on the server. However, to work around this, I have made a handy module that I’m willing to share:

local touched = {}

local function getTouchingParts(p)
	local con = p.Touched:Connect(function() end)
	local parts = p:GetTouchingParts()
	con:Disconnect()
	return parts
end

function touched.new(part)
	assert(
		part and typeof(part) == "Instance" and part:IsA("BasePart"),
		("Parameter 1 is invalid (BasePart expected, got %s)"):format(typeof(part))
	)

	local self = setmetatable({
		Part = part,
		Connection = nil,

		_PreviousParts = getTouchingParts(part),
	}, { __index = touched })

	coroutine.wrap(function()
		while true and wait() do
			if not part or not part.Parent then return self:Disconnect() end

			local parts = getTouchingParts(part)
			if parts == self._PreviousParts then continue end

			for _,tp in ipairs(parts) do
				if table.find(self._PreviousParts, tp) then continue end
				self.Connection(tp)
			end

			self._PreviousParts = parts
		end
	end)()

	return self
end

function touched:Connect(fn)
	assert(
		fn and typeof(fn) == "function",
		("Parameter 1 is invalid (function expected, got %s)"):format(typeof(fn))
	)

	self.Connection = fn

	return self
end

function touched:Disconnect()
	table.clear(self)
end

return touched
1 Like