How would I change a Part's color according to a gradient?

I am trying to make a marshmallow tool that will change it’s over time on contact with a hit box. However, I want the marshmallow to change its color according to a gradient, somewhat similar to this one:

I tried using the TweenService and setting the brown color to the goal, but that ended up making me an RGB marshmallow instead.

Code:

tweenService = game:GetService("TweenService")

local part = script.Parent.Marshmallow
local partTween = tweenService:Create(part, TweenInfo.new(30, Enum.EasingStyle.Bounce, Enum.EasingDirection.In, 0, false), {Color = Color3.new(86, 36, 36)})

workspace.CampfireHitbox.Touched:Connect(function()
	if partTween.PlaybackState ~= Enum.PlaybackState.Playing then
		partTween:Play()
	end
end)

workspace.CampfireHitbox.TouchEnded:Connect(function()
	if partTween.PlaybackState == Enum.PlaybackState.Playing then
		partTween:Pause()
	end
end)

Video of the behavior:

Thank you for your feedback!

I can give you this much info, but to stop it and restart it on command I think you can figure out. Let me know if you have any questions:

-- Note: Run this in a LocalScript for smoother tweens

local TweenService = game:GetService("TweenService")

local part = script.Parent
local cookGradient = script.UIGradient -- Create a UIGradient that looks like the one you want
local keypoints = cookGradient.Color.Keypoints

local COOK_TIME = 5 -- How long it takes for the part to fully cook

for i = 1, #keypoints-1 do
	-- Start the part at the first color, tween to the next
	local startColor = keypoints[i].Value
	local goalColor = keypoints[i+1].Value

	part.Color = startColor

	-- Must be linear easing style for a normal looking cook
	local tweenTime = (keypoints[i+1].Time - keypoints[i].Time) * COOK_TIME
	local partTween = TweenService:Create(part, TweenInfo.new(tweenTime, Enum.EasingStyle.Linear), {
		Color = goalColor
	})
	partTween:Play()

	partTween.Completed:Wait() -- Wait for the tween to stop before continuing
end

Edit: If you want the complete, efficient solution by Roblox, go with the post below.

You can use this function:

(Taken from the documentation itself.)

local function evalColorSequence(sequence: ColorSequence, time: number)
    -- If time is 0 or 1, return the first or last value respectively
    if time == 0 then
        return sequence.Keypoints[1].Value
    elseif time == 1 then
        return sequence.Keypoints[#sequence.Keypoints].Value
    end

    -- Otherwise, step through each sequential pair of keypoints
    for i = 1, #sequence.Keypoints - 1 do
        local thisKeypoint = sequence.Keypoints[i]
        local nextKeypoint = sequence.Keypoints[i + 1]
        if time >= thisKeypoint.Time and time < nextKeypoint.Time then
            -- Calculate how far alpha lies between the points
            local alpha = (time - thisKeypoint.Time) / (nextKeypoint.Time - thisKeypoint.Time)
            -- Evaluate the real value between the points using alpha
            return Color3.new(
                (nextKeypoint.Value.R - thisKeypoint.Value.R) * alpha + thisKeypoint.Value.R,
                (nextKeypoint.Value.G - thisKeypoint.Value.G) * alpha + thisKeypoint.Value.G,
                (nextKeypoint.Value.B - thisKeypoint.Value.B) * alpha + thisKeypoint.Value.B
            )
        end
    end
end

With a color sequence to make a gradient.

local timeValue = Instance.new("NumberValue")
timeValue.Value = 0
TweenService:Create(timeValue,TweenInfo.new(1),{Value = 1}):Play()
timeValue.Changed:Connect(function()
    part.Color = evalColorSequence(<sequence>,timeValue.Value)
end)

Replace <sequence> with your color sequence.

1 Like

How would I format the ColorSequence, is it a class of its own or some sort of Enum value?

A color sequence is basically what a gradient is. When editing a UIGradient, this pop up is just a visualisation of what the color sequence is

Here’s an example on how to write one:

-- If you want to use ColorSequenceKeypoints, they have to be in a table for
-- ColorSequence.new()
ColorSequence.new(
	{
		ColorSequenceKeypoint.new(0,Color3.new(1,0,0)), -- The first parameter is time
		ColorSequenceKeypoint.new(.5,Color3.new(0,1,0)),
		ColorSequenceKeypoint.new(1, Color3.new(0,0,1))
	}
)

How it looks:

If you want a simple gradient with 2 colors you can also just do:
ColorSequence.new(Color3.new(1,0,0),Color3.new(0,0,1))
How it looks:

There isn’t a way to get a color straight up yet but a user on the devforum has made a function you could use!

A color sequence is a class of it’s own by default in roblox. It can be used like so:

ColorSequence.new({
    ColorSequenceKeypoint.new(0,Color),
    ColorSequenceKeypoint.new(Time [0-1],Color),
    ColorSequenceKeypoint.new(1,Color)
})

It’s the same used for UIGradients and particles, trails, beams etc.

I have managed to create a script using cloudy’s technique.
The color sequence I took from the image using Firefox’s eyedropper.

Code if you want to make your own marshmallow:

local TweenService = game:GetService("TweenService")
local function evalColorSequence(sequence: ColorSequence, time: number)
	if time == 0 then
		return sequence.Keypoints[1].Value
	elseif time == 1 then
		return sequence.Keypoints[#sequence.Keypoints].Value
	end

	for i = 1, #sequence.Keypoints - 1 do
		local thisKeypoint = sequence.Keypoints[i]
		local nextKeypoint = sequence.Keypoints[i + 1]
		if time >= thisKeypoint.Time and time < nextKeypoint.Time then
			local alpha = (time - thisKeypoint.Time) / (nextKeypoint.Time - thisKeypoint.Time)
			return Color3.new(
				(nextKeypoint.Value.R - thisKeypoint.Value.R) * alpha + thisKeypoint.Value.R,
				(nextKeypoint.Value.G - thisKeypoint.Value.G) * alpha + thisKeypoint.Value.G,
				(nextKeypoint.Value.B - thisKeypoint.Value.B) * alpha + thisKeypoint.Value.B
			)
		end
	end
end


timeValue = script.timeValue

timeValue.Value = 0
partTween = TweenService:Create(timeValue,TweenInfo.new(30),{Value = 1})

sequence = ColorSequence.new( --Color sequence from my diagram
	{
		ColorSequenceKeypoint.new(0,Color3.fromHex("#f8f8f8")),
		ColorSequenceKeypoint.new(0.125,Color3.fromHex("#f7F5ba")), -- The first parameter is time
		ColorSequenceKeypoint.new(0.25,Color3.fromHex("#eec877")),
		ColorSequenceKeypoint.new(0.375,Color3.fromHex("#e79e38")),
		ColorSequenceKeypoint.new(0.5,Color3.fromHex("#b46d1f")),
		ColorSequenceKeypoint.new(0.625,Color3.fromHex("#74401b")),
		ColorSequenceKeypoint.new(0.75,Color3.fromHex("#371519")),
		ColorSequenceKeypoint.new(0.875,Color3.fromHex("#1c0c13")),
		ColorSequenceKeypoint.new(1,Color3.fromHex("#0b080a"))
	}
)
workspace.CampfireHitbox.Touched:Connect(function() --Play if in campfire hitbox
	if partTween.PlaybackState ~= Enum.PlaybackState.Playing and equip == true then
		partTween:Play()
	end	
end)

workspace.CampfireHitbox.TouchEnded:Connect(function() --Pause if not in the campfire hitbox
	if partTween.PlaybackState == Enum.PlaybackState.Playing and equip == true then 
		partTween:Pause()
	end
end)

script.Parent.Unequipped:Connect(function() --So the marshmallow doesn't cook in your backpack
	equip = false
	partTween:Pause()
end)

script.Parent.Equipped:Connect(function() --Resets equip
	equip = true
end)

timeValue.Changed:Connect(function()
	script.Parent.Marshmallow.Color = evalColorSequence(sequence,timeValue.Value)
end)

Video of the finished marshmallow product:

Thank you all for your very insightful and professional response!

No prob! Happy to have helped! : )

Your Original script here works

This is the only problem, Color3.New only inputs values from 0 to 1.
Just change it to

{Color = Color3.fromRGB(86, 36, 36)}

I appreciate your suggestion, but I wanted the part to follow the color gradient in my diagram/image.

If I follow your suggestion, my marshmallow turns gray then brown, which doesn’t look like a toasting marshmallow very much.

In addition, I wanted it to burn if roasted too long, but if I set the goal color to black, it would just look like a black-and-white marshmallow.

However, I appreciate your feedback!

1 Like

:+1: np, I saw that on previous replies back. I just wanted to correct your original mistake which was

ended up making me an RGB marshmallow instead.

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.