Is it fine for UI code to have 400+ lines, all just for animations?

I have a module script with, what I think is, too much code (around 430 lines or something), and all it currently does is make buttons animated and play sounds (that audio functionality is on a different module, so probably that doesn’t count?).

I’m planning to make many buttons appear differently animated and have different sounds (menu buttons popup with a noticeable click, while settings tickboxes sound like flicking a switch, but has no animations for example.)

Looking back at my code, I just felt like I’ve written too much just for animations, and I’ve only just started making a message functionality inside it (UI-wise). What’s worse, for me at least, is that I made two functions that make the animations and sounds when I interact with the buttons, yet those are still too long (around 70-80 lines, so probably about 140-160 total). The script also has many goal tables for multiple Tweens. And I’m planning to add more functions to achieve more effects so that my UI doesn’t look all too samey.

So, is having too much code just for GUI effects and animations bad? If it is, what are the other ways I could shorten my code? Thanks in advance.

Some snippets of my code that I think is too long for their intended purposes:

A bunch of goal tables.

-- -- Animation Values

local General_Button_Disabled_Info = TweenInfo.new(0.6, Enum.EasingStyle.Elastic, Enum.EasingDirection.Out)

local Main_Menu_Button_Default_Info = TweenInfo.new(0.3, Enum.EasingStyle.Quint)
local Main_Menu_Button_Hover_Info = TweenInfo.new(0.2, Enum.EasingStyle.Quad, Enum.EasingDirection.Out)
local Main_Menu_Button_Click_Info = TweenInfo.new(0.1, Enum.EasingStyle.Exponential, Enum.EasingDirection.Out)

local Main_Menu_Button_Default = {
	Button = {
		Size = UDim2.new(1, -8, 1, -8),
		BackgroundColor3 = Color3.fromRGB(255, 255, 255),
		TextColor3 = Color3.fromRGB(67, 67, 67)
	},
	Icon = {Scale = 1},
	IconColor = {ImageColor3 = Color3.fromRGB(113, 113, 113)}
}

local Main_Menu_Button_Hover = {
	Button = {
		Size = UDim2.new(1, -2, 1, -2),
		BackgroundColor3 = Color3.fromRGB(255, 162, 0),
		TextColor3 = Color3.fromRGB(255, 255, 255)
	},
	Icon = {Scale = 1.1},
	IconColor = {ImageColor3 = Color3.fromRGB(255, 255, 255)}
}

local Main_Menu_Button_Click = {
	Button = {
		Size = UDim2.new(1, -12, 1, -12),
		BackgroundColor3 = Color3.fromRGB(167, 89, 0),
		TextColor3 = Color3.fromRGB(255, 255, 255)
	},
	Icon = {Scale = .9},
	IconColor = {ImageColor3 = Color3.fromRGB(255, 255, 255)}
}

local Main_Menu_Button_Disabled = {
	Button = {
		Position = UDim2.new(0.5, 6, 0.5, 0) -- Offset is provided because of the shake effect.
	},
}

local Main_Menu_Button_DefaultNoColor = {
	Button = {
		Position = UDim2.new(0.5, 0, 0.5, 0) -- Offset is provided because of the shake effect.
	},
}

One of the functions I use to make a menu button.

-- the DuplicateTable just... duplicates tables.
module.Menu.Buttons.Apply_Animations = function(Target : Frame)
	-- Structure check
	local Frame = Target

	local Button : TextButton = Frame:FindFirstChild("Click")

	if not Button then return end

	Button.AutoButtonColor = false

	-- Colorize

	local Default = Main_Menu_Button_Default.Button
	local DefaultIcon = Main_Menu_Button_Default.IconColor

	local Hover = Main_Menu_Button_Hover.Button
	local HoverIcon = Main_Menu_Button_Hover.IconColor

	local Click = Main_Menu_Button_Click.Button
	local ClickIcon = Main_Menu_Button_Click.IconColor

	if Frame:GetAttribute("Disabled") == true then
		Button.BackgroundColor3 = Color3.fromRGB(220, 220, 220)
		Button.MouseButton1Click:Connect(function()
			local RejectAnimationBuildup = TweenService:Create(Button, Main_Menu_Button_Click_Info, Main_Menu_Button_Disabled.Button)
			local RejectAnimationRelief = TweenService:Create(Button, General_Button_Disabled_Info, Main_Menu_Button_DefaultNoColor.Button)

			SoundSystem.PlayOnce("Disabled")

			RejectAnimationBuildup:Play()
			wait(0.1)
			RejectAnimationRelief:Play()
		end)
		return
	else
		if Frame:GetAttribute("CustomColorsOverride") == true then

			Default = DuplicateTable(Main_Menu_Button_Default.Button)
			DefaultIcon = DuplicateTable(Main_Menu_Button_Default.IconColor)

			Hover = DuplicateTable(Main_Menu_Button_Hover.Button)
			HoverIcon = DuplicateTable(Main_Menu_Button_Hover.IconColor)

			Click = DuplicateTable(Main_Menu_Button_Click.Button)
			ClickIcon = DuplicateTable(Main_Menu_Button_Click.IconColor)

			Default.BackgroundColor3 = Frame:GetAttribute("DefaultColor")
			DefaultIcon.ImageColor3 = Frame:GetAttribute("IconDefaultColor")

			Hover.BackgroundColor3 = Frame:GetAttribute("HoverColor")
			HoverIcon.ImageColor3 = Frame:GetAttribute("IconHoverColor")

			Click.BackgroundColor3 = Frame:GetAttribute("ClickColor")
			ClickIcon.ImageColor3 = Frame:GetAttribute("IconClickColor")
		end
	end

	local Icon = Button:FindFirstChild("Icon")

	if not Icon then return end

	Button.BackgroundColor3 = Default.BackgroundColor3
	Button.TextColor3 = DefaultIcon.ImageColor3
	Icon.ImageColor3 = DefaultIcon.ImageColor3

	local ButtonAnims = {
		Default = TweenService:Create(Button, Main_Menu_Button_Default_Info, Default),
		Hover = TweenService:Create(Button, Main_Menu_Button_Hover_Info, Hover),
		Click = TweenService:Create(Button, Main_Menu_Button_Click_Info, Click),
	}

	local IconAnims = {
		Default = TweenService:Create(Icon.Scale, Main_Menu_Button_Default_Info, Main_Menu_Button_Default.Icon),
		Hover = TweenService:Create(Icon.Scale, Main_Menu_Button_Hover_Info, Main_Menu_Button_Hover.Icon),
		Click = TweenService:Create(Icon.Scale, Main_Menu_Button_Click_Info, Main_Menu_Button_Click.Icon),
	}

	local IconColorAnims = {
		Default = TweenService:Create(Icon, Main_Menu_Button_Default_Info, DefaultIcon),
		Hover = TweenService:Create(Icon, Main_Menu_Button_Hover_Info, HoverIcon),
		Click = TweenService:Create(Icon, Main_Menu_Button_Click_Info, ClickIcon),
	}

	local Pressing = false

	local PlayDefault = function()
		ButtonAnims.Default:Play()
		IconAnims.Default:Play()
		IconColorAnims.Default:Play()
	end

	Button.MouseEnter:Connect(function()
		ButtonAnims.Hover:Play()
		IconAnims.Hover:Play()
		IconColorAnims.Hover:Play()
		SoundSystem.PlayOnce("Hover", true, 0.1)
	end)

	Button.MouseLeave:Connect(function()
		PlayDefault()
		if Pressing then
			SoundSystem.PlayOnce("Cancel")
			Pressing = false
		end
	end)
	Button.MouseButton1Up:Connect(function()
		PlayDefault()
		if Pressing then
			SoundSystem.PlayOnce("Release")
		end
		Pressing = false
	end)

	Button.MouseButton1Down:Connect(function()
		ButtonAnims.Click:Play()
		IconAnims.Click:Play()
		IconColorAnims.Click:Play()
		SoundSystem.PlayOnce("Click", true, 0.1)
		Pressing = true
	end)
end
1 Like

You can try finding patterns between the two functions so you’re able to fuse them into one(with more parameters, features).

3 Likes

Having too many lines of code is never a bad thing in itself. It’s what those lines of code do that matters more than how long it is. For example, if your manually changing a value one line at a time to have it increase by 1 rather than using a for loop. That would be an example of long, inefficient code.

I can’t say which category your UI code falls into since you didn’t post it. But look at what the code does rather than how long it is and decide if it’s too much.

2 Likes

I believe my code is somewhat inefficient. I have some snippets of my module now on the main post (and some minor edits on my question too.) Are they bad code? Even though they work, I think I could make the code better now that it is starting to get harder for me to read.

1 Like