How do I tween a NumberSequence, can I?
Not directly, but you can always use an object that you can tween and map the value of that object to something you want to tween. In the example code below, I tweened a NumberValue and mapped the value of it to ColorSequence. You can use this code to gain a solid idea of how to do the same for a NumberSequence.
local TweenService = game:GetService('TweenService')
local NumberValue = Instance.new('NumberValue')
NumberValue:GetPropertyChangedSignal('Value'):Connect(function() -- Monitor NumberValue value change
script.Parent.Color = ColorSequence.new({
ColorSequenceKeypoint.new(0, Color3.new(1, 1, 1)),
ColorSequenceKeypoint.new(NumberValue.Value, Color3.new()), -- Inserting the number value into the ColorSequenceKeypoint
ColorSequenceKeypoint.new(1, Color3.new(1, 1, 1))
});
end)
local NumberTween = TweenService:Create(NumberValue, TweenInfo.new(1), { Value = 1 }) -- Creating the tween for the NumberValue
NumberTween:Play()
NumberTween.Completed:Wait()
NumberValue:Destroy() -- Garbage collect the NumberValue, no longer being used
There is no built-in way to tween a number sequence. However, you can code it all yourself.
The general premise is to get the time value of every unique keypoint in both NumberSequence
s provided and interpolate the value at each time value by a provided alpha
value. The diagram below explains this concept:
To create this, you need to create a function to evaluate the value at a certain time in a number sequence. To get the value of a NumberSequence
given a time, you can do the following:
local function evalNumberSequence(sequence: NumberSequence, time: number)
if time == 0 then
return sequence.Keypoints[1].Value, sequence.Keypoints[1].Envelope
elseif time == 1 then
return sequence.Keypoints[#sequence.Keypoints].Value, sequence.Keypoints[#sequence.Keypoints].Envelope
end
--> looping through keypoints until the time value fits in between two adjacent keypoints
for i = 1, #sequence.Keypoints - 1 do
local current = sequence.Keypoints[i]
local next = sequence.Keypoints[i + 1]
if time >= current.Time and time < next.Time then
local alpha = (time - current.Time) / (next.Time - current.Time)
return
current.Value + (next.Value - current.Value) * alpha,
current.Envelope + (next.Envelope - current.Envelope) * alpha
end
end
return 1, 1 --> value, envelope
end
This code is provided in the documentation for the NumberSequence
datatype.
Then, you can get all the unique points between each number sequence, and interpolate these anchor point values by a provided alpha
value. You can then use these acquired points
function(a: NumberSequence, b: NumberSequence, alpha: number)
-->> retrieving unique points
local pointTimes = {}
for _, Keypoint in a.Keypoints do
table.insert(pointTimes, Keypoint.Time)
end
for _, Keypoint in b.Keypoints do
if not table.find(pointTimes, Keypoint.Time) then
table.insert(pointTimes, Keypoint.Time)
end
end
table.sort(pointTimes) --> make sure the points are in order
-->> creating a new number sequence from interpolating all the values
local keypoints = {}
for _, pointTime in pointTimes do
local valA, envA = evalNumberSequence(a, pointTime)
local valB, envB = evalNumberSequence(b, pointTime)
table.insert(
keypoints,
NumberSequenceKeypoint.new(
pointTime,
valA + (valB - valA) * alpha,
envA + (envB - envA) * alpha
)
)
end
return NumberSequence.new(keypoints)
end
If you would like to use easing styles, you need to write the functions yourself. Here is a great resource that has code you can use to simulate the easing styles (note you have to convert this code to lua):