Any way to break this loop from RunService.Heartbeat?

Hello, I’ve been working on animating my overheadgui and I reached a point where the call script is doing as it should, but my issue is with my handler.

IsGradientEvent.OnServerEvent:Connect(function(player, IsGradient)
	local char = player.Character or player.CharacterAdded:Wait()
	local header = char:FindFirstChild("OverheadGui")
	local gradSELECT = header.Label:WaitForChild("SelectedPreset")
	local gradSELECT2 = header.Label3:WaitForChild("SelectedPreset")
	local gradchange = header.Label:WaitForChild("UIGradient")
	local gradchange2 = header.Label3:WaitForChild("UIGradient")
	
	-- Animation handle
	local button = gradchange
	local button1 = gradchange2
	local gradient = button
	local gradient1 = button1
	local ts = game:GetService("TweenService")
	local ti = TweenInfo.new(2, Enum.EasingStyle.Circular, Enum.EasingDirection.Out)
	local ti1 = TweenInfo.new(2, Enum.EasingStyle.Circular, Enum.EasingDirection.Out)
	local offset1 = {Offset = Vector2.new(1, 0)}	
	local offset2 = {Offset = Vector2.new(1, 0)}
	local endingPos = {Offset = Vector2.new(-1,0)}	
	local create = ts:Create(gradient, ti, offset1)	
	local create1 = ts:Create(gradient1, ti1, offset2)
	local createRev = ts:Create(gradient, ti, endingPos)	
	local create1Rev = ts:Create(gradient1, ti1, endingPos)
	local startingPos = Vector2.new(-1, 0) --start on the right, tween to the left so it looks like the shine went from left to right	
	local addWait = .005 --the amount of seconds between each couplet of shines

	print(IsGradient)
	
	gradient.Offset = startingPos
	gradient1.Offset = startingPos
	
	gradchange.Color = (GradientPresets[gradSELECT.Value])			
	gradchange2.Color = (GradientPresets[gradSELECT2.Value])
	
	local connection
	
	local function animate()
			create:Play()				
			create.Completed:Wait() --wait for tween to stop
			createRev:Play()

			create1:Play()					
			create1.Completed:Wait() --wait for tween to stop	
			create1Rev:Play()
	end
	
	
	if IsGradient == true then
		connection = RunService.Heartbeat:Connect(animate)
	elseif IsGradient == false  then
		gradchange.Color = (GradientPresets["Default"])			
		gradchange2.Color = (GradientPresets["Default"])
		connection = RunService.Heartbeat:Connect(animate)
		connection:Disconnect()
	end

Obviously, I know this is wrong. There’s been a bug where it’ll overlap the animation effect, where it’s unable to actually break that loop once the true condition is broken.

The general idea is, if toggled → selected gradient preset is seen by the server, converts it into a string and sets the .Color to the Value that is stored in a table. (These two components are working just fine.)

My issue is once that is passed and applied to the textlabel, the color shows and the animation is ran perfectly fine on the first run through. But, when you try to toggle, ideally it would set to the colorsequence to (essentially just 1,1,1) and disabled the animation loop from running so when clicked again, it’ll apply itself…again. I’ve tried so many different angles and this has been the only one that has been able to yield…relatively ok results.

I’m struggling with finding a way to break a loop that needs to run continuously to apply the effect.

I’m not sure what to set my conditional boolvalues to, in the sense what they need to call once either true or false is sent to the server. It’ll toggle between the colors and plain white – just won’t stop trying to run the animation loop. I’ve tried sticking conditionals inside the function but that hasn’t yielded much luck.

2 Likes

If you need more information, please let me know. I can do my best to provide more

Can you show what it does? Perhaps a video? This should be a pretty simple fix, but need visual confirmation of the issue.

1 Like

Yes. I can, give me a sec to record a playtest.

Also, just a note, you shouldn’t be looping this. Yielding in RunService events is an anti-pattern.

And now that I’ve watched the video, the Heartbeat is the issue.
Just call “animate()” and you should be fine.

If you want these two sequences to run together, just modify it to this.

2 Likes

I’ve been referencing the documentation on RunService, but I could’ve been understanding it wrong with trying to apply it to the functionality that I’m trying to accomplish.

Problematic Code Fixed:

    if IsGradient == true then
		animate()
	elseif IsGradient == false  then
		gradchange.Color = (GradientPresets["Default"])			
		gradchange2.Color = (GradientPresets["Default"])
		animate() -- should be correct.
	end
1 Like

That solved the overlapping problem, but my goal is to keep the loop running when IsGradient == true and to stop the animation and change the Color back to white when IsGradient == false. We’re halfway there now, that’s been more than I’ve accomplished so far.

That’s been the 2nd big hurdle I’ve been trying to accomplish.

p.s: Thanks for helping btw

I’ve got some stuff to tend to for a bit so I’ll have to help on this later, others are free to come assist you for now; I’ll be back later when I have time if it’s still not resolved by then.

2 Likes

Alright, thank you. I’m on my day off so I got all weekend to deal with this lol.

if IsGradient == true then
	while IsGradient == true do
		animate()
		wait()
	end
elseif IsGradient == false  then
	gradchange.Color = (GradientPresets["Default"])			
	gradchange2.Color = (GradientPresets["Default"])
end

This probably wont work but give it a try

It didn’t work, unfortunately.

It still runs through the loop once and then stops

Alright it was worth a shot though let me see if I can come up with something else

Sounds good, I’ve been bashing my head against the desk for the past week trying to figure out an approach to this. So far this has been yielding more success than failure.

I think you could try a IsGradient.Changed then put the loop in that

I don’t think the IsGradient.Changed approach will work, since I’m setting this up for multiple presets – I only set up 1 for testing.

–Unless i’m wrong

Try this then

while true do
	if IsGradient == true then
		animate()
	end
	wait()
end
if IsGradient == false then
	gradchange.Color = (GradientPresets["Default"])			
	gradchange2.Color = (GradientPresets["Default"])
end

I don’t expect it to but you should try it

the main problem is I’m only 80% sure what you are trying to achieve
that is through no fault of your own though

It’s alright, I’m trying to accomplish something I haven’t really seen /many/ people accomplish through a textlabel outside of just editing like… GUI buttons.

The idea is that “shine” sequence should just continue until you wanna turn it off or switch to another one.(I’ll worry about the other cases once I have a single working case.)

In that case see if the script I sent you works