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)
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.
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
-- 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))
}
)
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!