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

How do I fix this textbutton GUI brighten script from spazzing?

So there's a play button. When the player's mouse enters the play button, the play button gets brighter. When it leaves, it returns to its original green color by un-brightening. I've made a pretty good attempt at this, but there's one issue: when the mouse quickly enters it and quickly leaves, it alternates between brightening and un-brightening and results in a random color.

Just in case you need a visual, look at this GIF of the problem: http://i.imgur.com/dvY8WBh.gif.

Another: http://i.imgur.com/ugLFhrv.gif.

Here's a GIF of it working correctly: http://i.imgur.com/wasU1Gy.gif Notice how when the mouse enters, the GUI brightens. When the mouse leaves, it un-brightens to its original state.

And finally, here's the code:

complete = false -- used to check if the gui is done brightening
in_session = false -- used to know when to unbrighten 
left = false -- used to know when the mouse left the gui

textButton.MouseEnter:connect(function()
	brighten = coroutine.wrap(function() -- this function brightens the button
		for i = 1,37,4 do
			in_session = true
			textButton.BackgroundColor3 = Color3.new(i * 1/100 + textButtonR,i * 1/100 + textButtonG,i * 1/100 + textButtonB)
			wait()
			print(i)
			current_color = i --used to unbrighten at any stage of the brightening process just in case the player's mouse leaves while it's brightening. allows for unbrightening even if it's not 100% done brightening. 
			if i == 37 then   -- brighten function is done when it reaches 37
				complete = true
				print ("complete")
			end
		end
	end)	
	brighten() -- brightens the button when the mouse enters
end)

if left == true then -- if the mouse leaves, the brightening stops 
	brighten = coroutine.yield()
end

textButton.MouseLeave:connect(function()
	left = true -- if the mouse leaves, this variable is set to true 
	
	local unbrighten = coroutine.wrap(function() -- unbrightens the button to its original color. 
		for i = current_color,1,-4 do -- used to unbrighten if the mouse leaves during any stage of the brightening process.
			textButton.BackgroundColor3 = Color3.new(textButtonR+i/100,textButtonG+i/100,textButtonB+i/100)
			wait()
			print 'left'
		end
	end)
	
	if in_session then -- if the mouse left and the brighten function is going on, then unbrighten the button.
		unbrighten()
	end
end)

If you have any questions, I'll be happy to clarify. Thank you so much if you are able to solve my problem. By the way, this is not all of the code. I have omitted the code used to make the GUIs. If you want that, here's a pastebin of all code: http://pastebin.com/NKiqR0S8

EDIT: So I have managed to fix the original problem myself with some help from CreativeEnergy from the community chat. But now I am faced with a different problem: the button does not get brighter if the mouse enters the button while it is un-brightening.

GIF of the problem: http://i.imgur.com/yVb1bHv.gif Notice how when the mouse enters the button while the button is un-brightening, it doesn't brighten. But when it leaves, it unbrightens.

Here's my updated code:

complete = false -- used to check if the gui is done brightening
in_session = false -- used to know when to unbrighten 
left = false -- used to know when the mouse left the gui

textButton.MouseEnter:connect(function()
	brighten = coroutine.wrap(function() -- this function brightens the button
		for i = 1,37,4 do
			if not left then
				in_session = true
				textButton.BackgroundColor3 = Color3.new(i * 1/100 + textButtonR,i * 1/100 + textButtonG,i * 1/100 + textButtonB)
				wait()
				print(i)
				current_color = i --used to unbrighten at any stage of the brightening process just in case the player's mosue leaves while it's brightening.
				if i == 37 then   -- brighten function is done when it reaches 37
					complete = true
					print ("complete")
				end
			end
		end
	end)	
	if last_color == 1 or last_color == nil then
		brighten() -- brightens the button when the mouse enters
		print('yeah')
	elseif 1 < last_color then
		unbrighten = coroutine.yield()
		print('ok')
		for i = last_color,37,4 do 
			if not left then
				in_session = true
				textButton.BackgroundColor3 = Color3.new(i * 1/100 + textButtonR,i * 1/100 + textButtonG,i * 1/100 + textButtonB)
				wait()
				print(i)
				current_color = i --used to unbrighten at any stage of the brightening process just in case the player's mosue leaves while it's brightening.
				if i == 37 then   -- brighten function is done when it reaches 37
					complete = true
					print ("complete")
				end
			end
		end
	end
end)

if left == true then -- if the mouse leaves, the brightening stops 
	brighten = coroutine.yield()
end	


textButton.MouseLeave:connect(function()
	left = true -- if the mouse leaves, this variable is set to true 
	
	local unbrighten = coroutine.wrap(function() -- unbrightens the button to its original color. 
		for i = current_color,1,-4 do -- used to unbrighten if the mouse leaves during the brightening process.
			textButton.BackgroundColor3 = Color3.new(textButtonR+i/100,textButtonG+i/100,textButtonB+i/100)
			wait()
			print 'left'
			last_color = i
			if last_color == 1 then
				left = false
			end
		end
	end)
	
	if in_session then -- if the mouse left and the brighten function is going on, then unbrighten the button.
		unbrighten()
	end
end)

1 answer

✓ Accepted answer

Don't use coroutines: they're messy!

The key observation that simplifies these sorts of scripts is that you should describe this in terms of while hovering, not when enter.

You're currently describing it like this:

When the mouse enters, start brightening. When the mouse leaves, start darkening.

I recommend thinking about it like this:

If the mouse is currently hovering, brighten. If not, darken.

We need only one continuous loop, and we need to know if the mouse is hovering over the button:

textButton.MouseEnter:connect(function() hovering = true end)
textButton.MouseLeave:connect(function() hovering = false end)

while wait() do
	if hovering then
		brighten()
	else
		darken()
	end
end

darken and brighten will be like one iteration in your loops -- we just have to make sure they have a stop -- that's the purpose of the math.min and math.max.

This stops you from brightening more than the brightest (since it will not stop calling brighten(), brighten() needs to figure out how to not get too bright)

function rgb(color)
	return color.r, color.g, color.b
end

function darken()
	local r, g, b = rgb(textButton.BackgroundColor3)
	r, g, b = r - 1/25, g - 1/25, b - 1/25
	-- These are as dark as they get:
	r = math.max(r, 43/255)
	g = math.max(g, 130/255)
	b = math.max(b, 74/ 255)
	textButton.BackgroundColor3 = Color3.new(r, g, b)
end

function brighten()
	local r, g, b = rgb(textButton.BackgroundColor3)
	r, g, b = r + 1/25, g + 1/25, b + 1/25
	-- These are as bright as they get:
	r = math.min(r, 134/255)
	g = math.min(g, 221/255)
	b = math.min(b, 165/ 255)
	textButton.BackgroundColor3 = Color3.new(r, g, b)
end

(These functions need to go before the while loop)

1 comment

0

Words cannot express my gratitude. You're definitely a person to aspire to.

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