I’m trying to make a gradient do a full rotation using tweening whenever a button is pressed, and if the button is pressed again while the gradient is still rotating, it waits and doesn’t rotate a second time.
My issue is that the section with “print(“playback not finished yet”)” never runs, and I have no idea why.
I’ve tried a lot of other ways of achieving this, but none have worked, and the only possible solutions I can think of require writing way too much code then what should be necessary.
Here’s the specific code snippet from a bigger overall script:
local activetween = nil
local function rotateGradient(gradient)
local currentRotation = gradient.Rotation
local goal = { Rotation = currentRotation + 180 }
local gradtween = TweenService:Create(gradient, tweenInfoGradient, goal)
activetween = gradtween
if activetween.PlaybackState == Enum.PlaybackState.Playing then
activetween.Completed:Wait()
print("playback not finished yet")
else
gradtween:Play()
gradtween.Completed:Wait()
gradient.Rotation = 0
end
end
local buttons = {
Frame.Diagnostics.DiagnosisButton,
Frame.Diagnostics.HousePowerButton,
Frame.TopBar.DiagnosticsButton,
Frame.TopBar.StoreButton
}
for _, button in ipairs(buttons) do
button.MouseButton1Click:Connect(function()
print("enter")
rotateGradient(button.UIStroke.UIGradient)
end)
end
Let me be more clear, the “activetween” is supposed to save the tween so when the function is called again, it can check if it’s still playing. I forgot to mention that the “activetween = gradtween” I moved to the bottom of the function so it’s not overridden, but it still didn’t work even then.
It looks like you’re setting your activetween to equal gradtween before checking if the tween is playing? I’d recommend adding logic to check if activetween exists prior to setting it equal to gradtween.
Or setting activetween to gradtween if you don’t have a tween playing.
local activetween = nil
local function rotateGradient(gradient)
if nil ~= activetween then return end
local currentRotation = gradient.Rotation
local goal = { Rotation = currentRotation + 180 }
activetween = TweenService:Create(gradient, tweenInfoGradient, goal)
activetween:Play()
activetween.Completed:Wait()
gradient.Rotation = 0
activetween = nil
end
Im so confused what is even the point of activetween?
You want it to be an upvalue or something
local function rotateGradient(button:TextButton):()
local UIGradient = button.UIStroke.UIGradient::UIGradient
local activetween:Tween?
button.Activated:Connect(function()
local _activetween=activetween
if _activetween then
_activetween.Completed:Wait()
print("playback not finished yet")
else
local currentRotation = UIGradient.Rotation
local goal = { Rotation = currentRotation + 180 }
local gradtween = TweenService:Create(UIGradient, tweenInfoGradient, goal)
activetween=gradtween
gradtween:Play()
gradtween.Completed:Wait()
gradient.Rotation = 0
activetween=nil
end
end)
end
local temp = Frame.Diagnostics
rotateGradient(temp.DiagnosisButton)
rotateGradient(temp.HousePowerButton)
temp = Frame.TopBar
rotateGradient(temp.DiagnosticsButton)
rotateGradient(temp.StoreButton)
So basically what you’re saying is, you don’t want the tween to start again if there is already a tween playing?
I think you have it mostly correct but the thing is, You set the active tween variable (which I assume is a variable that contains a currently playing tween, if there is one) every time the functions runs and THEN check its state. Since you just set the active tween to a new one, the playback state will never be Playing.
So, it will create a tween, set the active tween to be that tween, checks if the active tween / gradtween is playing already, its not playing because it just got set to a new tween, so it plays the tween. I think this should be able to be fixed just with a simple change.
Here inside the rotateGradient function:
local function rotateGradient(gradient)
local currentRotation = gradient.Rotation
local goal = { Rotation = currentRotation + 180 }
local gradtween = TweenService:Create(gradient, tweenInfoGradient, goal)
-- previous place where you were setting the active tween
if activetween and activetween.PlaybackState == Enum.PlaybackState.Playing then
activetween.Completed:Wait()
print("playback not finished yet")
else
activetween = gradtween -- new location
gradtween:Play()
gradtween.Completed:Wait()
gradient.Rotation = 0
end
end
Basically what this does, instead it checks if the active tween is playing already before, if it is it will wait for it to finish and run your print statement.
If it doesn’t exist or isn’t playing, then it will play the tween and set the active tween.
That somewhat worked, as in it works when dealing with one button. However, for all the other buttons there’s a new issue, which is that if I click any other button, the rotation on the gradient doesn’t play for the other buttons. (I probably should’ve been more clear in my original post so let me be more specific)
Here’s a little image I made, basically I want it so that the border (that has a gradient) does a spin whenever clicked per button. It seems to work good for one button now, but clicking any of the others while one of the gradients on any of the buttons are still spinning makes it so they also don’t play.
Hmmmm, ok so from what I see you have it so the tween’s are all handled by one script for all of the buttons? Interesting.
Ok, so this might be a little bit complicated, but we are now going to change the system to use a table that keys the current button being pressed, and to check if the current buttons active tween is playing or not, so that it works with multiple.
So since you already pass through a unique Gradient value, we can use that. Here is the code:
local activetweens = {} -- it is now an empty table. Changed the name to add an s to the end, since it stores multiple now.
local function rotateGradient(gradient)
local currentRotation = gradient.Rotation
local goal = { Rotation = currentRotation + 180 }
local gradtween = TweenService:Create(gradient, tweenInfoGradient, goal)
if activetweens[gradient] and activetweens[gradient].PlaybackState == Enum.PlaybackState.Playing then
activetween.Completed:Wait()
print("playback not finished yet")
else
activetweens[gradient] = gradtween
gradtween:Play()
gradtween.Completed:Wait()
gradient.Rotation = 0
end
end
local buttons = {
Frame.Diagnostics.DiagnosisButton,
Frame.Diagnostics.HousePowerButton,
Frame.TopBar.DiagnosticsButton,
Frame.TopBar.StoreButton
}
for _, button in ipairs(buttons) do
button.MouseButton1Click:Connect(function()
print("enter")
rotateGradient(button.UIStroke.UIGradient)
end)
end
This should work considering multiple buttons.
You can visualize the table being like {Frame.Diagnostics.DiagnosisButton.UIStroke.UIGradient = tween here} and basically since that key is different for every button, it can get different tweens / tween playback states depending on the button that was pressed.
From what I am seeing, gradtween is a newly created tween. When you do: “if activetween.PlaybackState == Enum.PlaybackState.Playing then”, you are essentially checking if the newly created gradtween is playing. Which it won’t play because every time the function is called, a new tween gets created. I think what you should do is store the creation of the tween outside the function (not creating a new tween everytime you run the function)
Edit: My replies to this reply might be more helpful
local function rotateGradient(gradient)
local currentRotation = gradient.Rotation
local goal = { Rotation = currentRotation + 180 }
local gradtween = TweenService:Create(gradient, tweenInfoGradient, goal)
if activetween.PlaybackState == Enum.PlaybackState.Playing then
activetween.Completed:Wait()
print("playback not finished yet")
else
activetween = gradtween
gradtween:Play()
gradtween.Completed:Wait()
gradient.Rotation = 0
end
end
local function rotateGradient(gradient)
if activetween.PlaybackState == Enum.PlaybackState.Playing then
activetween.Completed:Wait()
print("playback not finished yet")
return
end
local currentRotation = gradient.Rotation
local goal = { Rotation = currentRotation + 180 }
local gradtween = TweenService:Create(gradient, tweenInfoGradient, goal)
activetween = gradtween
gradtween:Play()
gradtween.Completed:Wait()
gradient.Rotation = 0
end
I can’t say I fully understand this (I’m still working on getting better at coding), but it DOES work, though I also get an error in the console, too for some reason.
local activetweens = {} -- it is now an empty table. Changed the name to add an s to the end, since it stores multiple now.
local function rotateGradient(gradient)
local currentRotation = gradient.Rotation
local goal = { Rotation = currentRotation + 180 }
local gradtween = TweenService:Create(gradient, tweenInfoGradient, goal)
if activetweens[gradient] and activetweens[gradient].PlaybackState == Enum.PlaybackState.Playing then
activetweens[gradient].Completed:Wait() -- fixed line, forgot to update this
print("playback not finished yet")
else
activetweens[gradient] = gradtween
gradtween:Play()
gradtween.Completed:Wait()
gradient.Rotation = 0
end
end
local buttons = {
Frame.Diagnostics.DiagnosisButton,
Frame.Diagnostics.HousePowerButton,
Frame.TopBar.DiagnosticsButton,
Frame.TopBar.StoreButton
}
for _, button in ipairs(buttons) do
button.MouseButton1Click:Connect(function()
print("enter")
rotateGradient(button.UIStroke.UIGradient)
end)
end