Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
COMMUNITY QUESTION

Intermediate transparency tweening?

So this is a HUGE problem that I'm having, that I just can't seem to solve. Basically, I'm trying to make a function that tweens the transparency of a GUI, which isn't a problem.


The problem is, I'm also trying to make it so if I call the tween function again, before the first one has finished, it will still tween it's transparency to the proper end point without glitching or adding ridiculous numbers. Here's my code for this so far:

local Gui = {}
Gui.CurrentlyTweening = {}

-- params
-- #1 the GUI object
-- #2 the starting transparency
-- #3 the ending transparency
-- #4 the step variant for the for loop
function Gui:TweenTrans(gui,start,stop,step)

	-- check the map for old key
	if self.CurrentlyTweening[gui] then
		self.CurrentlyTweening[gui] = nil
	end

	-- add this key to the map
	self.CurrentlyTweening[gui] = true

	-- adjust the step variant
	step = start > stop and -step or step

	-- for loop
	spawn(function()
		for i = start,stop,step do
			
			-- if the key has been removed from the map, stop the loop
			-- and if you look above, you'll see the key will be set to nil
			-- if the function is called again before this loop finishes
			if not self.CurrentlyTweening[gui] then
				break
			end

			-- change transparency
			gui.BackgroundTransparency = i
			wait()
		end

		self.CurrentlyTweening[gui] = nil -- remove it at the end of the loop
	end)
end

return Gui

And it doesn't error, but it glitches horribly and doesn't work as expected, where I start getting insane transparency numbers. This is what I want the final result to look like: https://gyazo.com/44b4a9c6adfda38dd7d67861f44abfc4

Kinda like the TweenSize or TweenPosition method, where you can have a boolean argument that allows you to "interrupt" a current tweening process, and override it with a new one. So when I try something like this:

Gui:TweenTrans(gui,0,1,0.01) -- tween it from fully visible to fully invisible
wait(1) -- wait one second
Gui:TweenTrans(gui,1,0,0.01) -- (the first transition should still be running), interrupt the current one and smoothy tween it from it's current transparency, to it's end point.

But instead, I get a result like this: https://gyazo.com/deb7febd18082cba1e6b8bba3d3812b6 where it doesn't seem to be stopping the first tween process. I feel like I'm going about this completely the wrong way, and I'd really appreciate it if someone could help.


Thanks for taking the time to read this.

1 comment

0

Question1 : how is this being iterated? Question 2 : following that answer, I could create a smoother transition if you'd like.

1 answer

So heres a silky smooth version. Calling your code: Heres an example version

local Gui = require(script.Gui)
local UserInputService = game:GetService('UserInputService')
local player = game.Players.LocalPlayer
local gui = player.PlayerGui.ScreenGui.Frame

UserInputService.InputBegan:connect(function(mousecheck)
	if mousecheck.KeyCode == Enum.KeyCode.Q then
		Gui:TweenTrans(gui,0,1,1)--(gui,start,stop,Time)
	end	
end)



UserInputService.InputEnded:connect(function(mousecheck)
	if mousecheck.KeyCode == Enum.KeyCode.Q then
		Gui:TweenTrans(gui,1,0,1)--(gui,start,stop,Time)
	end	
end)

Thats just an example of how it works. HOLD Q in test mode, it'll dissapear, realease, it'll re-appear. And your module element:

local Gui = {}
	Gui.CurrentlyTweening = {}
	
	local RunService = game:GetService('RunService')
	RunService:BindToRenderStep("GUITransparency", Enum.RenderPriority.Camera.Value, function()
		for _,GUIS in pairs(Gui.CurrentlyTweening) do
			GUIS.Path.BackgroundTransparency = Vector3.new(GUIS.Start,0,0):lerp(Vector3.new(GUIS.Stop,0,0),tick()-GUIS.Started/GUIS.Time).X
			if GUIS.Path.BackgroundTransparency == GUIS.Stop then
				Gui.CurrentlyTweening[GUIS] = nil -- remove from table.
			end
		end
	end)
	function Gui:TweenTrans(gui,start,stop,step)
	    if self.CurrentlyTweening[gui] then
	        self.CurrentlyTweening[gui] = nil
	    end
	    Gui.CurrentlyTweening[gui]={["Path"]=gui;["Start"]=start;["Stop"]=stop;["Time"]=step;["Started"]=tick()}	
	end
return Gui

So, to clarify, two changes. 1, you are no longer iterating. I mean, you are, but its over a percentage, which is controlled by changing the "Step" value, into your desired length of transition.

2, you are using RenderStepped and lerping. By using the percentage equation, even if you have low frames (which might make some players have a really long transparency transition using the for i=1,X stepping system), you will still end up with the same result, regardless of framerate on every client!

If you need a hand utilizing this properly, lemme know :) And hey, if its not what you're after, point me diretly at the scripts and I'll try and tackle it today for ya.

This discussion is preserved as it was. New answers, comments, and votes are closed.