How to create a simple rainbow effect using TweenService

So, I’ve never posted a topic here before, but I decided to give it a shot. I’ll be showing you how you can make a rainbow color (or RGB / Chroma) effect using TweenService. I’m fairly certain this would be the best performing option to do this, so I’d suggest this over any other method.

Let’s start by defining our TweenService and making our Tweening function.

local TweenService = game:GetService("TweenService")

local function SimpleTween(Object, Length, Style, Direction, Properties)
	local Tween = TweenService:Create(
		Object,
		TweenInfo.new(Length, Enum.EasingStyle[Style].Value, Enum.EasingDirection[Direction].Value),
		Properties
	)
	
	Tween:Play()
	Tween.Completed:Wait()
	Tween:Destroy()
end

Now, you can define what object you want to tween, I’ll be using a regular Frame, which means I’m going to be using BackgroundColor3 for my rainbow effect.

local TweenService = game:GetService("TweenService")
local Frame = script.Parent

local function SimpleTween(Object, Length, Style, Direction, Properties)
	local Tween = TweenService:Create(
		Object,
		TweenInfo.new(Length, Enum.EasingStyle[Style].Value, Enum.EasingDirection[Direction].Value),
		Properties
	)
	
	Tween:Play()
	Tween.Completed:Wait()
	Tween:Destroy()
end

Now, to do the actual color changing effect, we’re going to start by making a while true do end at the bottom of our script, and we’re going to put in six SimpleTween function calls.

local TweenService = game:GetService("TweenService")
local Frame = script.Parent

local function SimpleTween(Object, Length, Style, Direction, Properties)
	local Tween = TweenService:Create(
		Object,
		TweenInfo.new(Length, Enum.EasingStyle[Style].Value, Enum.EasingDirection[Direction].Value),
		Properties
	)
	
	Tween:Play()
	Tween.Completed:Wait()
	Tween:Destroy()
end

while true do
	SimpleTween(Frame, 1, "Linear", "Out", { BackgroundColor3 = Color3.new() })
	SimpleTween(Frame, 1, "Linear", "Out", { BackgroundColor3 = Color3.new() })
	SimpleTween(Frame, 1, "Linear", "Out", { BackgroundColor3 = Color3.new() })
	SimpleTween(Frame, 1, "Linear", "Out", { BackgroundColor3 = Color3.new() })
	SimpleTween(Frame, 1, "Linear", "Out", { BackgroundColor3 = Color3.new() })
	SimpleTween(Frame, 1, "Linear", "Out", { BackgroundColor3 = Color3.new() })
end

Now the order of the colors is red, yellow, green, light blue (toothpaste), blue, and finally pink, which means our loop should look something like this.

while true do
	SimpleTween(Frame, 1, "Linear", "Out", { BackgroundColor3 = Color3.new(1, 0, 0) })
	SimpleTween(Frame, 1, "Linear", "Out", { BackgroundColor3 = Color3.new(1, 1, 0) })
	SimpleTween(Frame, 1, "Linear", "Out", { BackgroundColor3 = Color3.new(0, 1, 0) })
	SimpleTween(Frame, 1, "Linear", "Out", { BackgroundColor3 = Color3.new(0, 1, 1) })
	SimpleTween(Frame, 1, "Linear", "Out", { BackgroundColor3 = Color3.new(0, 0, 1) })
	SimpleTween(Frame, 1, "Linear", "Out", { BackgroundColor3 = Color3.new(1, 0, 1) })
end

The effect produced is a very simple rainbow effect, which should look like this.

Thanks for reading!

Here’s another version that @legoracer suggested.

local t = 5; --how long does it take to go through the rainbow

while wait() do
	local hue = tick() % t / t
	local color = Color3.fromHSV(hue, 1, 1)
	--> set the color
end

And here’s my modified version.

local t = 5; --how long does it take to go through the rainbow

local tick = tick
local fromHSV = Color3.fromHSV
local RunService = game:GetService("RunService")
local Frame = script.Parent

RunService:BindToRenderStep("Rainbow", 1000, function()
	local hue = tick() % t / t
	local color = fromHSV(hue, 1, 1)
	Frame.BackgroundColor3 = color
end)
40 Likes

This could be achieved easier by using Çolor.fromHSV(hue, sat, val)¸

Example :

local t = 5; --how long does it take to go through the rainbow

while wait() do
	local hue = tick() % t / t
	local color = Color3.fromHSV(hue, 1, 1)
	--> set the color
end
34 Likes

That version is definitely better, but what I was going for was a smaller hit on performance, since I’ve never found a version that wasn’t a framerate killer. Yours definitely works amazing as well, and it’s pretty fast too.

This version is nicer than the one I had originally, I’ll put it up for sure.

local t = 5; --how long does it take to go through the rainbow

local tick = tick
local fromHSV = Color3.fromHSV
local RunService = game:GetService("RunService")
local Frame = script.Parent

RunService:BindToRenderStep("Rainbow", 1000, function()
	local hue = tick() % t / t
	local color = fromHSV(hue, 1, 1)
	Frame.BackgroundColor3 = color
end)
17 Likes