So I'm working on a puzzle game that uses Portal-style "put the cube on the button" mechanics.

For the buttons, I'm using this script:

script.Parent.Touched:connect(function(activator)
	if activator.Name == "Activator" then
		script.Parent.BrickColor = BrickColor.new("Sea green")
		script.Parent.SurfaceLight.Color = Color3.new(0,170/255,127/255)
		script.Parent.Parent.Particles.ParticleEmitter.Color = ColorSequence.new(Color3.new(0,170/255,127/255),Color3.new(0,170/255,127/255))	
	end
end)

script.Parent.TouchEnded:connect(function()
	local shouldBeActive = getTouchingParts()
	if shouldBeActive == false then
		script.Parent.BrickColor = BrickColor.new("Plum")
		script.Parent.SurfaceLight.Color = Color3.new(1,0,1)
		script.Parent.Parent.Particles.ParticleEmitter.Color = ColorSequence.new(Color3.new(1,0,1),Color3.new(1,0,1))
	end
end)

function getTouchingParts()
	local num = 0
	for i,v in pairs(script.Parent:GetTouchingParts()) do
		if v.Name == "Activator" then
			num = num + 1
		end
	end
	if num == 0 then
		return false
	else
		return true
	end
end

It works, but it's buggy. My main problem is that it occasionally fails to register the touch happening or ending.

I dunno what to do; making it a while loop simply returns a script timeout.