UIGradientPlus
About
UIGradientPlus is a wrapper class for UIGradient instances that expands upon their basic functions, providing a wide range of new visual effects. Unfortunately, the default UIGradient class has limited capabilities, which restricts the number use cases for it in Studio. While there are workarounds for some of these limitations, many are quite complex and often considered not worth the effort.
UIGradientPlus streamlines these workarounds and provides a simple API to work with. Using this module, you can create custom UIGradients and apply animations like loops. While it may not seem like much, just a few new effects can be used to create countless unique, dynamic gradient designs.
Performance
While this module is by no means fully optimized, most modern machines can easily handle hundreds of UIGradientPlus objects with animations simultaneously with little to no FPS drop.
The module also manages cleanup and the destruction of objects efficiently. While there may still be a few bugs, destroying a UIGradientPlus object should leave nothing behind since everything will be garbage collected automatically.
Over 300 gradients with animations easily running at 100+ FPS
PLEASE NOTE:
This module is still in its alpha development stage. This means many features are yet to be implemented, and existing features may have some performance issues or bugs.
Features
Revamped API:
One of the main issues with UIGradients is that their keypoints are limited to the domain [0, 1]. This means you can’t have extra gradient segments off to the side, and it makes looping animations or doing anything relating to offsetting the gradient a nightmare.
The Offset property itself is also problematic since it stores a Vector2 value and acts completely separate from the Rotation property. This means simply offsetting a gradient at an angle requires trigonometry, which can get annoying and computationally expensive.
UIGradientPlus solves these issues by allowing you to scale gradients beyond the size of their parent Instance and changing Offset from a Vector2 to a number, using Rotation to determine its angle.
Animations:
While many gradient animations are impossible to recreate in Studio, there are still many that you can get working with some ingenuity. UIGradientPlus currently supports two animations that can be mixed together: Loop and Rotate.
These animations support easing styles and easing directions just like Tween objects, and they can also be set to repeat multiple times within a single animation cycle.
I will definitely be adding more animations in the future, but these two alone can create some very unique gradients. If the current animations aren’t enough, you can easily custom-script your own using the module’s offset system.
Animation Examples
Looping & Rotating Animations
Pulsing & Striped Effects
Metatable Proxy:
UIGradientPlus objects use a metatable that allows you to seamlessly edit both the core UIGradient instance and the wrapper table. While this is more of a QOL feature than an actual improvement, it saves a good deal of time when creating complex custom effects.
QOL Features:
- Default properties table
- Color parsing (
string→Color3) - Type checking and autocomplete
- Reusable animation objects
Other features like error handling are planned but haven’t been implemented yet since I’m currently focusing on polishing the core features.
Usage
Creating UIGradientPlus Objects
Creating a UIGradientPlus Object:
Creating a UIGradientPlus object can be a bit complicated if you are changing a lot of properties, but it should be pretty easy once you figure out what you’re doing. The constructor takes in 2 arguments: properties and parent. parent is self-explanatory, and all you have to do for the properties table is put the property’s value at the index of the its name.
local UIGradientPlus = require(game:GetService("ReplicatedStorage").UIGradientPlus)
local UIGradientTest = UIGradientPlus.new({
-- Keypoint tables are an exception since sequences are constructed later
colorKeypoints = {
{0, Color3.fromHSV(184 / 360, 1, 1)},
{0.5, Color3.fromHSV(275 / 360, 1, 1)},
{1, Color3.fromHSV(184 / 360, 1, 1)},
},
transparencyKeypoints = {
{0, 0},
{0.5, 1},
{1, 0},
},
-- Otherwise follow the format propertyName = propertyValue
scaleValue = 2,
offsetValue = 0,
looped = true,
-- Custom properties use camelCase while Roblox properties use PascalCase
Rotation = 90,
Enabled = true,
Name = "UIGradient",
}, workspace.Part.SurfaceGui.Frame) -- Parent
Important Notes:
- UIGradientPlus should be stored in
ReplicatedStorageso both the server and client can access it - Values in the
defaultstable will be used for any properties not specified in the constructor - The module uses
offsetValue(number) instead ofOffset(Vector2) - If
loopedis set totrueand there are keypoints with different values at times 0 and 1, they will be set to the same value
Managing UIGradientPlus Animations
Applying an Animation to a UIGradientPlus Object:
To create or apply an animation to a UIGradientPlus object, just call the ApplyAnimation() method with either a properties table or previous animation object. The properties table for this method works exactly the same as the one used in the constructor.
local loopAnimation = UIGradientTest:ApplyAnimation({
animationType = "Loop",
duration = -1,
speed = 1,
easingSpeed = 1,
easingStyle = Enum.EasingStyle.Linear,
easingDirection = Enum.EasingDirection.In,
})
Important Notes:
ApplyAnimation()returns a shallow copy of the animation object for future use- If
loopedis not set totrue, the Loop animation will not work properly - If
durationis less than or equal to 0, the animation will play indefinitely - if easingSpeed is half of one, the easing style will play twice in a full animation cycle (and so on)
Pausing or Resuming an Animation:
To pause or resume an animation, call the corresponding method with the animation object as the argument.
UIGradientTest:PauseAnimation(loopAnimation)
task.wait(1)
UIGradientTest:ResumeAnimation(loopAnimation)
Removing an Animation from a UIGradientPlus Object:
To remove an animation, just call :RemoveAnimation() with the animation object as the argument.
task.wait(10)
UIGradientTest:RemoveAnimation(loopAnimation)
Tip: Generally try to have only one of each animation type playing at once unless they align well (same speed, easingSpeed, etc.)
Destroying UIGradientPlus Objects
Destroying a UIGradientPlus Object:
Just call :Destroy(), it’s that easy. The method removes the metatable and clears the self table, preparing the object for garbage collection.
UIGradientTest:Destroy()
Other Info
Changelog:
Version 1.0.0 (Alpha)
Initial release of the ModuleScript (Alpha)
Version Date: 6/16/25
Version Store Page: UIGradientPlus 1.0-alpha
Version 1.1.0 (Alpha)
Revamps, Optimizations, and Easing Styles
Version Date: 6/21/25
Version Store Page: UIGradientPlus 1.1-alpha
Changes:
- QOL Features:
- Type checking
- Color parsing
- Various optimizations & changes
- Updated Systems:
- Revamped
defaultstable - Revamped constructor argument names and formats
- Optimized
processKeypoints()function - Optimized
UpdateGradient()method (ReplacedInterpolateKeypoints())
- Revamped
- New Features and Methods:
- Animation easing styles
- New methods
SetColorKeypoints()andSetTransparencyKeypoints() - New methods
PauseAnimation()andResumeAnimation()
Hotfix 1.1.1 (Alpha)
Type Checking and Method Chaining
Version Date: 6/24/25
Version Store Page: UIGradientPlus 1.1-alpha
Changes:
- Fixed type checking autofill and inconsistencies
- Fixed
SetColorKeypoints()andSetTransparencyKeypoints()not updating the gradient - Added method chaining
PLEASE NOTE:
UIGradients have a plethora of rendering bugs that I am unable to fix, these can usually be observed when the gradient is at an oblique angle, but can really happen anywhere.
Most info on the module can be found in this post, but if you have any feedback or questions, feel free to reply and I will try to respond within a day or two.
Also, since the module is in alpha, please inform me of any bugs you find because there are various edge cases that might make the code explode.