Hello developers, I want to make an animation that acts on 2 coordinates independently of them, but since in the usual case of using TweenService {Position = scaleX, offsetX, scaleY, offsetY} all coordinates are required, this means, for example, TimeX = 1 s, TimeY = 0.5 s will not be possible.
For this question and the answer to it, it is required to make an animation in the form of a moving Frame along the trajectory of Infinity\8.
Of course, it is possible to do this using RenderStep, but I would like not to use it.
After thinking about this for a while and reading a couple posts, I think it isn’t possible to tween like this since it would require 2 TweenInfos which would then require 2 tweens which don’t work at the same time.
In case you didn’t know though, TweenService has a method called :GetValue which can be easily used to create tween like movements (easing style, easing direction).
Render step shouldn’t be any more costly on performance for this so unless there is a specific issue, render step is the way to go.
Example:
local TWEEN_TIME = 1
local EASING_STYLE = Enum.EasingStyle.Sine
local EASING_DIRECTION = Enum.EasingDirection.InOut
local GUI_END_X = 0.5
local GUI_END_Y = 0.5
local timePassed = 0
local connection = RunService.RenderStep:Connect(function(deltaTime: number)
timePassed += deltaTime
if timePassed > TWEEN_TIME then connection:Disconnect() end
local alpha = TweenService:GetValue(
timePassed / TWEEN_TIME,
EASING_STYLE,
EASING_DIRECTION
)
GUI.Position = UDim2.fromScale(GUI_END_X * alpha, GUI_END_Y * alpha)
end)
(Of course you should probably make this a function)
local TWEEN_TIME = 1
local EASING_STYLE_X = Enum.EasingStyle.Sine
local EASING_DIRECTION_X = Enum.EasingDirection.InOut
local EASING_STYLE_Y = Enum.EasingStyle.Linear
local EASING_DIRECTION_Y = Enum.EasingDirection.InOut
local GUI_END_X = 200
local GUI_END_Y = 100
local connection = RunService.RenderStep:Connect(function(deltaTime: number)
timePassed += deltaTime
-- End function (prevent memory leaks)
if timePassed > TWEEN_TIME then connection:Disconnect() end
-- 2 alphas to control the position of either axis
local alphaX = TweenService:GetValue(
timePassed / TWEEN_TIME,
EASING_STYLE_X,
EASING_DIRECTION_X
)
local alphaY = TweenService:GetValue(
timePassed / TWEEN_TIME,
EASING_STYLE_Y,
EASING_DIRECTION_Y
)
-- Changed this to from offset
GUI.Position = UDim2.fromOffset(GUI_END_X * alphaX, GUI_END_Y * alphaY)
end)
If you want this to play infinitely, just wrap it in a function and you can call the function repeatedly without much problem.
Basically, “stack” the tweens. In your case, I’d imagine a structure like this:
FrameOuter (fully transparent)
FrameInner (contains your image/logo/whatever)
FrameInner is tweened to move infinitely left/right with Sine easing at 0.5s duration
FrameOuter is tweened to move infinitely up/down with Sine easing at 1s duration
local Frame = script.Parent
local StopButton = script.Parent.Parent.TextButton
local Bounce = false
local Speed = 2
local connection
local XOffset = 100
local YOffset = 50
local function Infinity()
local TimePassed = 0
connection = game:GetService("RunService").RenderStepped:Connect(function(delta)
TimePassed += delta
local scale = 2 / (3 - math.cos(2 * TimePassed * Speed))
local x = scale * math.cos(TimePassed * Speed)
local y = scale * math.sin(2 * TimePassed * Speed) / 2
Frame.Position = UDim2.new(0.5 , XOffset * x - XOffset, 0.5, YOffset * y - YOffset)
end)
end
StopButton.MouseButton1Down:Connect(function()
if Bounce then
connection:Disconnect()
Bounce = false
else
Infinity()
Bounce = true
end
end)