Highlighting interactable objects causes a little lag

I have this system mostly working, but for some reason when the player moves their mouse off the interactable object the game freezes for about 0.5 - 1 seconds. How can I stop this from happening?
The current code:

local TweenService = game:GetService("TweenService")
local plr = game.Players.LocalPlayer
local mouse = plr:GetMouse()
mouse.Icon = "http://www.roblox.com/asset/?id=9925913476"

local prompt = script.Parent.Parent:WaitForChild("InterectGUI").TextButton
local infoGUI = script.Parent.Parent:WaitForChild("InterectGUI").InteractionText

local highlight
game:GetService("RunService").RenderStepped:Connect(function()
	if mouse.Target then
		local clickDetector = mouse.Target:FindFirstChildOfClass("ClickDetector")
		
		if clickDetector then
			clickDetector.MouseHoverEnter:Connect(function()
				highlight = game:GetService("ReplicatedStorage").InteractHighlight:Clone()
				highlight.Parent = mouse.Target.Parent
				prompt.Text = mouse.Target:FindFirstChildOfClass("ClickDetector").Name
				local targetPosition = UDim2.new(0.371, 0, 0.926, 0)
				local tweenInfo = TweenInfo.new(0.25)
				local tween = TweenService:Create(prompt, tweenInfo, {Position = targetPosition})
				tween:Play()
			end)
			
			clickDetector.MouseHoverLeave:Connect(function()
				if game.Workspace:FindFirstChild("InteractHighlight",true) then
					game.Workspace:FindFirstChild("InteractHighlight",true):Destroy()
				end
				local targetPosition = UDim2.new(0.371, 0, 1, 0)
				local tweenInfo = TweenInfo.new(0.25)
				local tween = TweenService:Create(prompt, tweenInfo, {Position = targetPosition})
				tween:Play()
			end)
		end
	end
end)

Thank you in advance.

2 Likes
game:GetService("RunService").RenderStepped:Connect(function()
	clickDetector.MouseHoverEnter:Connect(function()
		...
	end)
	
	clickDetector.MouseHoverLeave:Connect(function()
		...
	end)
end)

Every time you cann Connect you create a new connection object, and the exact cause of this is that the MouseHoverLeave listener is called 100s of times if you’ve hovered for just a few seconds. This number grows over time, at like 60 per second.

One solution is to use Once instead of Connect, e.g.:

game:GetService("RunService").RenderStepped:Connect(function()
	local target = mouse.Target
	if not target then return end

	local clickDetector = target:FindFirstChildOfClass("ClickDetector")
	if not clickDetector then return end

	if highlight.Parent and highlight.Parent == target.Parent then return end --The mouse is still over the same thing, no need to do anything

	--The mouse just started hovering something different
	prompt.Text = clickDetector.Name
	highlight.Parent = target.Parent
	tweenTo(prompt, UDim2.fromScale(0.371, 0.926))

	clickDetector.MouseHoverLeave:Once(function()
		highlight.Parent = nil
		tweenTo(prompt, UDim2.fromScale(0.371, 1))
	end)
end)

That’s fixed the lag issue, but another problem has arisen. The interactions don’t have a high range, so the highlight should only appear when the player is within the ClickDetector’s MaxActivationDisatance. Now it has infinite range and the player can hightlight interactables no matter how far away they are.
(I edited the code a little, as it didn’t like the undefined tweenTo function, but maybe I’m just being stupid and inefficient lol)

local highlight = game:GetService("ReplicatedStorage").InteractHighlight--:Clone()
game:GetService("RunService").RenderStepped:Connect(function()
	local target = mouse.Target
	if not target then return end

	local clickDetector = target:FindFirstChildOfClass("ClickDetector",true)
	if not clickDetector then return end
	
	if highlight.Parent and highlight.Parent == target.Parent then return end --The mouse is still over the same thing, no need to do anything

	--The mouse just started hovering something different
	prompt.Text = clickDetector.Name
	highlight.Parent = target.Parent
	local targetPosition = UDim2.new(0.371, 0, 0.926, 0)
	local tweenInfo = TweenInfo.new(0.25)
	local tween = TweenService:Create(prompt, tweenInfo, {Position = targetPosition})
	tween:Play()

	clickDetector.MouseHoverLeave:Once(function()
		highlight.Parent = nil
		local targetPosition = UDim2.new(0.371, 0, 1, 0)
		local tweenInfo = TweenInfo.new(0.25)
		local tween = TweenService:Create(prompt, tweenInfo, {Position = targetPosition})
		tween:Play()
	end)
end)

Whoops forgot tweenTo:

function tweenTo(guiObject, position)
	local tweenInfo = TweenInfo.new(0.25)
	local tween = TweenService:Create(guiObject, tweenInfo, { Position = position })
	tween:Play()
	return tween
end

Use it if you’d like, or don’t ^.^

Here’s how you can add the range check:

game:GetService("RunService").RenderStepped:Connect(function()
	local target = mouse.Target
	if not target then return end
	if not (target.Position - character:GetPivot().Position).magnitude <= range then return end
	...

Thank you so much for your help, you’re a lifesaver!

1 Like

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