How to wait without pausing entire script

run.RenderStepped:Connect(function()
 -- there was code here which i removed for convenience
	if mouse.Target and mouse.Target:FindFirstChild("AttachmentHighlight") then
		mouse.Target.AttachmentHighlight.Enabled = true
		repeat task.wait() until not mouse.Target:FindFirstChild("AttachmentHighlight")
	end
end)

I made a script for weapon attachments which enables a highlight when the player’s mouse is on the attachment. I want the highlight to turn back off when the player takes their mouse off the attachment.

What I would normally do is:

repeat task.wait() until not mouse.Target:FindFirstChild("AttachmentHighlight")

The issue with this is task.wait() pauses the entire script, and I wouldn’t have a way to refer to the highlight after the loop is finished. I can’t use delay(time, function) because it’s not a set amount of time

Simple but it is not recommended to have many loops

task.spawn(function()
	repeat task.wait() until not mouse.Target:FindFirstChild("AttachmentHighlight")
	-- Code
end)

Difficult but better for performance

run.RenderStepped:Connect(function()
	local AttachmentHighlight = mouse.Target:FindFirstChild("AttachmentHighlight")
	if mouse.Target and AttachmentHighlight then
		AttachmentHighlight.Enabled = true
		
		local Connection = nil
		Connection = mouse.Target.ChildRemoved:Connect(function(Object)
			if Object ~= AttachmentHighlight then		return		end
			Connection:Disconnect()
			-- Code
		end)
	end
end)

The AttachmentHighlight is never removed, it’s just enabled and disabled based off it’s enabled property, so this event would never run when the attachment highlight is unselected

I’ll just use this for now since I have to get going soon, this could provide a temporary fix. Efficiency is the least of my worries, if you had saw the rest of my script, you would know why :skull:

Anyways, I’ll mark this as a solution for now. Thank you for your help