GUI Movement along 2 coordinates

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)

I’ll add an image of what I think about all this

Does this work?

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.

Yeah, well if you want to use this function you’re gonna need more than 1 tween (call the function multiple times to go forward and backward).

ok i try it, thanks you for help

Pretty sure you can use both Sin and Cos to create an infinity/figure-8 symbol such as this. This makes it so you only have one variable, t for time.

can you please write a formula with using sin or cos for that, im bad in math :stuck_out_tongue:

https://gamedev.stackexchange.com/questions/43691/how-can-i-move-an-object-in-an-infinity-or-figure-8-trajectory

1 Like

Can’t you technically separate each dimensions with their own individual frames?

local TS = game:GetService("TweenService")

local Player = game:GetService("Players").LocalPlayer
local ScreenUi = Player.PlayerGui:WaitForChild("ScreenGui")

local XFrame = ScreenUi.XFrame
local YFrame = XFrame.YFrame

TS:Create(XFrame, TweenInfo.new(5), {Position = UDim2.fromOffset(600, 0)}):Play()
TS:Create(YFrame, TweenInfo.new(1), {Position = UDim2.fromOffset(0, 600)}):Play()

I believe you’re looking for this:

Here’s the link to the devforum post: [Advanced UI] Introduction to 2D Animations

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

1 Like

Yea that works, thank you very much!
Code:

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)

1 Like

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