How to fill a gradient based on any amount of color values and positions

At the moment, I have this basic setup for coloring a gradient based on 4 given color values and positions

local ADDITION = 0.001

local Floors = {
	[1] = {
		Color = Color3.fromRGB(255, 0, 0),
		Size = 30
	},
	[2] = {
		Color = Color3.fromRGB(85, 255, 0),
		Size = 25
	},
	[3] = {
		Color = Color3.fromRGB(0, 85, 255),
		Size = 10
	},
	[4] = {
		Color = Color3.fromRGB(255, 170, 255),
		Size = 40
	}
}

-- Get total size of tower
for _, v in pairs(Floors) do
	TotalSize += v.Size
end

-- Get the floor percentages
local Percentages = {}

for i, v in pairs(Floors) do
	local Previous = Percentages[i - 1] or 0
	Percentages[i] = Previous + (v.Size / TotalSize)
end

Frame.Backing.UIGradient.Color = ColorSequence.new{
		ColorSequenceKeypoint.new(0, Floors[1].Color),
		ColorSequenceKeypoint.new(Percentages[1], Floors[1].Color),
		
		ColorSequenceKeypoint.new(Percentages[1] + ADDITION, Floors[2].Color),
		ColorSequenceKeypoint.new(Percentages[2], Floors[2].Color),
		
		ColorSequenceKeypoint.new(Percentages[2] + ADDITION, Floors[3].Color),
		ColorSequenceKeypoint.new(Percentages[3], Floors[3].Color),
		
		ColorSequenceKeypoint.new(Percentages[3] + ADDITION, Floors[4].Color),
		ColorSequenceKeypoint.new(1, Floors[4].Color)
	}

and it works fine, however, I want it to be automatic, so if I have 2 floors, or 50 floors, it can automatically fill it in, without me having to write long lines of code. Is there anyway to fill it using a for loop or something?

Currently what it does, and the desired effect
image

You can loop through the table (Percentages) and use the code already demonstrated in your code to add in the same way. In a few minutes I’ll try and give you a code sample.

I’m unsure exactly what you mean? I tried something like this

-- Set floor color
for i, v in pairs(Percentages) do
	if i == 1 then continue end -- Don't do bottom
	
	if i == #Floors then continue end -- Don't do top
	
	Frame.Backing.UIGradient.Color = ColorSequence.new({
		-- Set bottom
		ColorSequenceKeypoint.new(0, Floors[1].Color),
		ColorSequenceKeypoint.new(Percentages[1], Floors[1].Color),
		
		-- Set between
		ColorSequenceKeypoint.new(Percentages[i] + ADDITION, Floors[i + 1].Color),
		ColorSequenceKeypoint.new(Percentages[i + 1], Floors[i + 1].Color),
		
		-- Set top
		ColorSequenceKeypoint.new(Percentages[#Floors - 1] + ADDITION, Floors[#Floors].Color),
		ColorSequenceKeypoint.new(1, Floors[#Floors].Color)
	})
end

Well I think I’m about to be done with my solution so just give me a few minutes, because honestly I’m having a bit of trouble myself :sweat_smile:. I don’t use UIGradients very often so this is new to me.

1 Like

Finally finished the script :grin:, and here it is:

local frame = script.Parent
local addOffset = 0.001

local floors = {
	{
		Color = Color3.fromRGB(255,0,0),
		Size = 30
	},
	{
		Color = Color3.fromRGB(85, 255, 0),
		Size = 25
	},
	{
		Color = Color3.fromRGB(0, 85, 255),
		Size = 10
	},
	{
		Color = Color3.fromRGB(255, 170, 255),
		Size = 40
	}
}

local function calculatePercentage(number,full)
	return (number/full)
end

local floorPercentages = {}

local totalFloorSize = 0

for i,v in ipairs(floors) do
	totalFloorSize += v.Size
end

--yeah i know it might be inefficient to run through the table twice

for i,v in ipairs(floors) do
	floorPercentages[i] = {Color = v.Color, Size = calculatePercentage(v.Size, totalFloorSize)}
end

local gradientStepOne = {
	{Color = Color3.new(0,0,0),Time=0}
}

local previousSize = 0
for i,v in ipairs(floorPercentages) do
	gradientStepOne[#gradientStepOne+1] = {Color = floorPercentages[i].Color, Time = 				previousSize+addOffset}
	gradientStepOne[#gradientStepOne+1] = {Color = v.Color, Time = previousSize+v.Size}
	previousSize += v.Size
end

local function TableToColorSequence(t)
	local construct = {}
	for i, info in ipairs(t) do
		construct[i] = ColorSequenceKeypoint.new(info.Time, info.Color)
		print(i, info.Time, info.Color)
	end

	return ColorSequence.new(construct)
end

local finishedGradient = TableToColorSequence(gradientStepOne)

script.Parent.UIGradient.Color = finishedGradient

This code could probably be more efficient, but that isn’t the point. So, when you modify this script to add/remove levels, all you need to change is the floors table.

Explanation

Explanation:

I’ll go through each part of the script one by one and explain how it works.

First, the two variables at the top define the frame that the UIGradient is applying to and the offset between levels to make the change more abrupt. The layout I made in the explorer looks like this:
image
“FullBar” is the frame being referenced to in the script.

Secondly, is the floors table. It simply uses a similar format to the one you made, with Color and Size being defined within each smaller dictionary. This is what you change to modify the stages/levels and such.

Next, the calculatePercentage() function. This function simply just takes the size of one level, divides it by the size of all of the levels combined, and creates a size value useable by the UIGradient.

Afterwards, the floorPercentages table is defined, and shortly after is filled with values from the floors table, but in the percentage form I mentioned before.

Then, the gradientStepOne table is defined. This table is the final table being used before it is converted to a ColorSequence. It starts defined with

{Color = Color3.new(0,0,0),Time=0}

which is a part to prevent blending of the first stage’s color with the black. Then the table is filled out with values that are doubled up to prevent blending, as shown in this for loop:

local previousSize = 0
for i,v in ipairs(floorPercentages) do
    gradientStepOne[#gradientStepOne+1] = {Color = floorPercentages[i].Color, Time = previousSize+addOffset}
    gradientStepOne[#gradientStepOne+1] = {Color = v.Color, Time = previousSize+v.Size}
    previousSize += v.Size
end

(ignore the gray text, I’m pretty sure it’s forum formatting for comments in some other coding language)

After the table is filled, it is converted to a color sequence by this function, actually using the code from this forum topic:

local function TableToColorSequence(t)
	local construct = {}
	for i, info in ipairs(t) do
    	construct[i] = ColorSequenceKeypoint.new(info.Time, info.Color)
		print(i, info.Time, info.Color)
	end

	return ColorSequence.new(construct)
end

At this point, all you have to do is set the Color value of the UIGradient, as done here:

local finishedGradient = TableToColorSequence(gradientStepOne)

It ends up looking like this:

Have a nice day/night :smiley:

1 Like