Problems with .Touched Event

Hi devs,

I’m working on a Roblox script using .Touched events to detect when a hitbox touches other parts. However, I noticed that the .Touched event only fires if both the hitbox and the touched part have CanCollide = true.

If either part has CanCollide = false, the event doesn’t trigger, even if the parts visually overlap or seem to touch.

Is this the intended behavior in Roblox physics? Is there a way to make .Touched fire if only one part has CanCollide = true, or when the hitbox is invisible but still detects hits?

Here’s the script:

function Weather.summonThunder(endPos, numSegments, segmentLength)
	local thunderParts = {}

	local startPos = Vector3.new(endPos.X, endPos.Y + numSegments * segmentLength, endPos.Z)
	local currentPos = startPos

	playThunderSound(endPos)

	for i = 1, numSegments do

		local deviationX = math.random(-3, 3)
		local deviationZ = math.random(-3, 3)

		local nextPos = currentPos + Vector3.new(deviationX, -segmentLength, deviationZ)
		local direction = nextPos - currentPos

		local boltPart = Instance.new("Part")
		boltPart.Anchored = true
		boltPart.CanCollide = false
		boltPart.CanTouch = false
		boltPart.Material = Enum.Material.Neon
		boltPart.Color = BOLT_COLOR
		boltPart.Size = Vector3.new(BOLT_WIDTH, length, BOLT_WIDTH)
		boltPart.CFrame = CFrame.new(currentPos:Lerp(nextPos, 0.5), nextPos) * CFrame.Angles(math.rad(90), 0, 0)
		boltPart.Name = "ThunderSegment"
		boltPart.Transparency = BOLT_TRANSPARENCY
		boltPart.Parent = workspace

		local hitboxPart = Instance.new("Part")
		hitboxPart.Anchored = true
		hitboxPart.CanTouch = true
		hitboxPart.CanCollide = false
		hitboxPart.Transparency = 1
		hitboxPart.Size = Vector3.new(3, length, 3)
		hitboxPart.CFrame = boltPart.CFrame
		hitboxPart.Name = "ThunderHitbox"
		hitboxPart.Parent = workspace

        --Here!!

		hitboxPart.Touched:Connect(function(hit)
			if hit:IsA("BasePart") and hit ~= hitboxPart and hit ~= boltPart then
				print("Lightning touched part: " .. hit.Name)
			end
		end)

		table.insert(thunderParts, boltPart)
		table.insert(thunderParts, hitboxPart)
		currentPos = nextPos
	end

	for _, part in pairs(thunderParts) do
		Debris:AddItem(part, BOLT_LIFETIME)
	end
end

It should work regardless of if they can collide, do you have BasePart.CanTouch set to true on both the parts?

1 Like

As @nowodev said it should work with just .CanTouch enabled but I suggest using spatial queries for hitboxes as they are generally more reliable than the phyisics based .Touched.

I don’t believe this is true actually, there’s no reason Touched events would be any less reliable than spatial queries, it’s handled by the physics engine, so anything that a spatial query would detect, Touched would too as long as you have it set up correctly. You don’t clip through walls just by walking into them do you?

From my own testing, Touched is actually a bit more reliable than spatial queries in certain situations, particularly “bounces”, where the part never visually overlaps due to physics pushing it away.
Touched is occasionally behind by 1 frame from spatial queries, due to the engine not immediately detecting a collision after simulation step, but it will detect it the next frame.


(Also note the significantly higher script activity for spatial queries)
Green = Touched, Red = Touch Ended, Pink (Touch Events) = Touch and Touch Ended fired in the same frame.


There are of course some situations where a spatial query would be better, for example:

  • instantaneous hit checking, for things like an AoE attack.
  • Detecting touches when the part is already touching

But I don’t think Touched events are “unreliable” like the myth says.

That is true, but for me its worth it.

Alright, as a 6+ years programmer on the platform, I had my experiences with .Touched, it mostly fired too many times per touch (causing high ping and low framerate), fired late (sometimes) and overall it wasn’t a too great experience with it.

I don’t want to criticize your claims as I think they are true but in the long term .Touched as more probability to “break”, in the ways I said and experienced.

I do agree that .Touched is still faster to use and less complicated to setup and understand.

But Roblox introduced spatial queries for more precise detections, which I think are the better solution here.

Nice to hear responses on this argument as, for me, its very intresting and still an open discussion between developers on Roblox.

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