Tween being incredibly slow when trying to make a highlight transparent

I’m not using the sample description.

So, my work is pretty simple: making a selection system with highlights. I got it to work well, but I’ve noticed that the disappearing tween (when you unfocus your mouse off of an interactable object) is INCREDIBLY SLOW, even though I’ve specified 0.2 as the duration in the TweenInfo.

I’m genuinely unsure why is this happening. Sure, setting the time to be a really low number might solve it, but it’d be nice if I could use a single number for the tweens rather than two separate ones.

  • LocalScript (location: game → StarterPlayer → StarterPlayerScripts)
local ts = game:GetService("TweenService")
local rs = game:GetService("RunService")

local player = game.Players.LocalPlayer
local mouse = player:GetMouse()
local character = player.Character
local selector = game.ReplicatedStorage:WaitForChild("Selector")

local interacts = {}

repeat wait() until game:IsLoaded()

for i, v in pairs(workspace:GetDescendants()) do
	if v:FindFirstChild("Interactable") and v:IsA("BasePart") then
		table.insert(interacts, v)
	end
end
print(interacts)

for i, v in pairs(interacts) do
	local clone = selector:Clone()
	clone.OutlineTransparency = 1
	clone.Enabled = true
	clone.Adornee = v
	clone.Parent = v
end

function hideAll()
	for i, v in pairs(interacts) do
		local outline = v:FindFirstChildWhichIsA("Highlight")
		if outline then
			hide(outline)
		end
	end
end

function hide(outline:Highlight)
	if not outline or outline.OutlineTransparency == 1 then return end
	local info = TweenInfo.new(0.2, Enum.EasingStyle.Quad, Enum.EasingDirection.In)
	local Tween = ts:Create(outline, info, {OutlineTransparency = 1})
	Tween:Play()
end

function show(outline:Highlight)
	if not outline or outline.OutlineTransparency == 0 then return end
	local info = TweenInfo.new(0.2, Enum.EasingStyle.Quad, Enum.EasingDirection.Out)
	local Tween = ts:Create(outline, info, {OutlineTransparency = 0})
	Tween:Play()
end

rs.Heartbeat:Connect(function()
	local target = mouse.Target
	if not target then hideAll() return end
	
	local targetHighlight = target:FindFirstChildWhichIsA("Highlight")
	if targetHighlight and table.find(interacts, target) then
		show(targetHighlight)
	else
		hideAll()
	end
end)

Any help appreciated! (like I said, I know how to fix this issue, I just want to know why is it happening in the first place)

For anyone looking for a video as proof:

1 Like

Ok, so every heartbeat after the mouse loses the target block hideall is run, in turn creating a new tween with a 0.2 duration from the starting transparency, which has only had around 16ms to run and fade the tween.
Each tween is cancelled each time and a new one created, to resolve the conflict, which is fine but it takes time, and when this happens every single heartbeat it adds up.

Thanks for the explanation!

Is there any way to combat this issue (besides lowering the tweentime)?

Yes, ideally you only want to call the tween once. Also you only need to hide those with highlights, not everything in the interacts table.

I would:
Create a new empty table.
Change the show function so it adds the object to the table.
Change the hideall function to loop through the new table.
Change the hide function to remove the object from the table.
Change the heartbeat function to find objects in the new table instead of interacts.

Sounds like a lot, but it should only be one or two line changes for each.
It should only check for objects with active highlights once and hide them once.

Hope it helps.

Hi!

I tried changing the script to fit what you just said. (I decided to do it 'cuz the game was laggy)

Have I done it right? Do I need to change anything?

local ts = game:GetService("TweenService")
local rs = game:GetService("RunService")

local player = game.Players.LocalPlayer
local mouse = player:GetMouse()
local character = player.Character
local selector = game.ReplicatedStorage:WaitForChild("Selection"):WaitForChild("Selector")

local current = selector.Parent:WaitForChild("CurrentSelect")
local oldSelect = nil

local interacts = {}
local visible = {}

repeat wait() until game:IsLoaded()

task.spawn(function()
	while task.wait(5) do
		for i, v in pairs(workspace:GetDescendants()) do
			if v:FindFirstChild("Interactable") and v:IsA("BasePart") then
				if not table.find(interacts, v) then
					table.insert(interacts, v)
				end	
			end
		end
		print(interacts)
		
		for i, v in pairs(interacts) do
			if v:FindFirstChildWhichIsA("Highlight") then continue end
			local clone = selector:Clone()
			clone.OutlineTransparency = 1
			clone.Enabled = true
			clone.Adornee = v
			clone.Parent = v
		end
	end
end)

function hideAll()
	for i, v in pairs(visible) do
		local outline = v -- :FindFirstChildWhichIsA("Highlight")
		if outline then
			hide(outline)
		end
	end
	current.Value = nil
end

function hide(outline:Highlight)
	if not outline or outline.OutlineTransparency == 1 then return end
	local info = TweenInfo.new(0.2, Enum.EasingStyle.Quad, Enum.EasingDirection.In)
	local Tween = ts:Create(outline, info, {OutlineTransparency = 1})
	Tween:Play()
	
	for i, v in pairs(visible) do
		if v == outline then
			table.remove(visible, i)
		end
	end
end

function show(outline:Highlight)
	if not outline or outline.OutlineTransparency == 0 then return end
	local info = TweenInfo.new(0.2, Enum.EasingStyle.Quad, Enum.EasingDirection.Out)
	local Tween = ts:Create(outline, info, {OutlineTransparency = 0})
	Tween:Play()
	table.insert(visible, outline)
end

rs.Heartbeat:Connect(function()
	local target = mouse.Target
	if not target then hideAll() return end
	
	local targetHighlight = target:FindFirstChildWhichIsA("Highlight")
	
	if targetHighlight and table.find(interacts, target) then
		--print("Selectable object found!")
		
		--print(player.Character)
		if player.Character then
			local distance = (target.Position - player.Character.PrimaryPart.Position).Magnitude
			--print(distance)
			if distance < 10 then
				if oldSelect then 
					local oldHighlight = oldSelect:FindFirstChildWhichIsA("Highlight")
					hide(oldHighlight) 
				end
				current.Value = target
				show(targetHighlight)
			else
				hideAll()
			end
		else
			hideAll()
		end	
		--[[
		if oldSelect then 
			local oldHighlight = oldSelect:FindFirstChildWhichIsA("Highlight")
			hide(oldHighlight) 
		end
		current.Value = target
		show(targetHighlight)
		]]
	else
		--print("No selectable object found. Unselecting all...")
		hideAll()
	end
	
	oldSelect = current.Value
end)

mouse.Button1Up:Connect(function()
	if current.Value ~= nil then
		current.Parent:WaitForChild("InteractInit"):FireServer(current.Value)
	end
end)

(Please note that I continued the script with interactions, so it’s a bit more than the original)

1 Like

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