I've been working on an all-in-one mouse tool script, and have been having issues with getting selection boxes to display correctly. Everything works fine, except the selection boxes will flash constantly and I have no idea how to fix it. It seems the target is constantly un-registering and re-registering. I've tried making an idle checker , but even that didn't work. Here's the important code --

local mouse = game.Players.LocalPlayer:GetMouse()
local debounce = false
local debounce1 = false
local debounce2 = false
local debounce3 = false
local maintarg 

-- The next 3 functions are called upon by the function at the bottom, to save some reading

function Empty(target)
	if not debounce1 then
		debounce1 = true
		local selectionBox = Instance.new("SelectionBox", target) 
		selectionBox.Adornee = target 
		selectionBox.Color = BrickColor.new("Really red")
		repeat wait() until maintarg ~= target 
		selectionBox:Destroy()
	end
	debounce1 = false
end

function Storage(target)
	if not debounce2 then
		debounce2 = true
		local selectionBox = Instance.new("SelectionBox",target) 
		selectionBox.Adornee = target 
		selectionBox.Color = BrickColor.new("Bright orange")
		repeat wait() until maintarg ~= target
		selectionBox:Destroy()
	end
	debounce2 = false
end

function Housing(target)
	if not debounce3 then
		debounce3 = true
		local selectionBox = Instance.new("SelectionBox",target)
		selectionBox.Adornee = target 
		selectionBox.Color = BrickColor.new("Lime green")
		repeat wait() until maintarg ~= target
		selectionBox:Destroy()
	end
	debounce3 = false
end

mouse.Move:connect(function()
	if not debounce then
		debounce = true
    	if mouse.Target then -- doesn't always catch skyboxes
			local maintarget = mouse.Target.Parent.Parent -- That's the model for all blocks in my game
			if mouse.Target and mouse.Target.Parent.Parent:FindFirstChild("type0") then -- a second check will protect from skyboxes
        		Empty(mouse.Target.Parent.Parent)

			elseif mouse.Target and mouse.Target.Parent.Parent:FindFirstChild("type1") then
        		Storage(mouse.Target.Parent.Parent)

			elseif mouse.Target and mouse.Target.Parent.Parent:FindFirstChild("type2") then
        		Housing(mouse.Target.Parent.Parent)

			else
				maintarg = "Nil" -- Precautionary measure
			end
    	end
		debounce = false
	end
end)

I've tried many things to get the flashing to end, but haven't yet accomplished it. I get the feeling the issue comes up with the repeat wait() until, or like I stated earlier, a changing target.

The camera is in "Scripted" if that matters.

Thank you for reading, and I look forward to fixing this annoying issue.

EDIT: I just tried adding coroutines to the script, since I'm quite sure the repeat wait() until pause was the culprit. However, it's not working correctly. This is the modified code with coroutines and an idle checker --

local mouse = game.Players.LocalPlayer:GetMouse()
local debounce = false
local debounce1 = false
local debounce2 = false
local debounce3 = false
local maintarg 
local selection
local moving = false
local debounceI = false

function Empty(target)
local EmptyC = coroutine.create(function()
    if not debounce1 then
		debounce1 = true
		local selectionBox = Instance.new("SelectionBox", target) 
		selectionBox.Adornee = target 
		selectionBox.Color = BrickColor.new("Really red")
		repeat wait() until maintarg ~= target and moving == true
		selectionBox:Destroy()
	end
	debounce1 = false
end)
end

function Storage(target)
local StorageC = coroutine.create(function()
    if not debounce2 then
		debounce2 = true
		target:FindFirstChild("InfoStorage", true).Enabled = true
		local selectionBox = Instance.new("SelectionBox",target) 
		selectionBox.Adornee = target 
		selectionBox.Color = BrickColor.new("Bright orange")
		repeat wait() until maintarg ~= target and moving == true
		target:FindFirstChild("InfoStorage", true).Enabled = false
		selectionBox:Destroy()
	end
	debounce2 = false
end)
end

function Housing(target)
local HousingC = coroutine.create(function()
    if not debounce3 then
		debounce3 = true
		target:FindFirstChild("InfoHousing", true).Enabled = true
		local selectionBox = Instance.new("SelectionBox",target)
		selectionBox.Adornee = target 
		selectionBox.Color = BrickColor.new("Lime green")
		repeat wait() until maintarg ~= target and moving == true
		target:FindFirstChild("InfoHousing", true).Enabled = false
		selectionBox:Destroy()
	end
	debounce3 = false
end)
end

mouse.Move:connect(function()
	moving = true
	if not debounce then
		debounce = true
    	if mouse.Target ~= nil then
			local maintarget = mouse.Target.Parent.Parent
			if mouse.Target and mouse.Target.Parent.Parent:FindFirstChild("type0") then
        		Empty(mouse.Target.Parent.Parent);

			elseif mouse.Target and mouse.Target.Parent.Parent:FindFirstChild("type1") then
        		Storage(mouse.Target.Parent.Parent);

			elseif mouse.Target and mouse.Target.Parent.Parent:FindFirstChild("type2") then
        		Housing(mouse.Target.Parent.Parent);

			else
				maintarg = "Nil"
			end
    	end
		debounce = false
	end
end);

mouse.Idle:connect(function()
	if not debounceI then
		debounceI = true
		moving = false
		debounceI = false
	end
end)

This code isn't doing anything, since nothing seems to be executing after calling the functions containing the coroutines.

I also tried using coroutine.wrap instead of create, though it didn't work because the coroutines died and stopped the script, and to my knowledge, couldn't be revived.