How do i tween a variable?

so i have a vector2 variable and id like to tween it, however when you tween the first argument has to be an instance. is there a more effective way than creating two separate values for the X and Y parameters and tweening them separately?

2 Likes

I usually just use a value object. If you want code to run every time it updates, put it in the GetPropertyChangedSignal connection.

local TweenService = game:GetService("TweenService")
local tweenInfo = TweenInfo.new(3)

local variable = Vector2.new(0, 0)
local value = Instance.new("Vector3Value")

value:GetPropertyChangedSignal("Value"):Connect(function()
    variable = Vector2.new(value.Value.X, value.Value.Y)
end)

TweenService:Create(value, tweenInfo, {Value = Vector3.one * 10}):Play()

-- Should tween the variable from (0,0) > (10, 10) throughout 3 seconds. Might bug, haven't tested.

I haven’t tested this out yet but if there are issues they should be easily fixed.

3 Likes

If you’re not someone who drools over performance, this is great.
Otherwise, you can use TweenService.GetValue along with a for loop / RenderStep / PreRender loop.

1 Like

A method I used to tween variables around was using task.wait()/RunService.RenderStepped and loops.
Using task.spawn is usually necessary in order to avoid the code from delaying until the tween ends.
Since it’s only limited to the basic tweening, it worked pretty well until i found a better method for tweening, so it’s not recommended to run this again while the tween is still active.
Originally this uses benchmarking, but i’m trimming it out so it doesn’t end up looking too complicated.

local TwS = game:GetService("TweenService")

local tweenInfo = TweenInfo.new(3)
local Variable1 = Vector2.new()

function tweenVariable1(target,twInfo)
   local elapsed = 0
   local original = Variable1
   repeat
      local alpha = math.clamp(elapsed / twInfo.Time,0,1)
      Variable1 = original:Lerp(target,TwS:GetValue(alpha,twInfo.EasingStyle,twInfo.EasingDirection))
      elapsed += task.wait()
   until alpha == 1
end

task.spawn(tweenVariable1,Vector2.new(10,5),tweenInfo) -- Allows the tween to run without yielding
-- or
tweenVariable(Vector2.new(10,5),tweenInfo) -- yields the current code until the tween finishes
4 Likes

What I do is Tween a NumberValue as a timescale, i.e. from 0 to 1, or more succinctly from 0% to 100% and multiply the percentage of completion with whatever you want to Tween.

For example:

-- t = time over which to interpolate
-- es = Easing Style to interpolate over
-- ed = Easing Direction to interpolate over
-- rev = switch to reverse tween when finished
function makeTimeTable(t:number,es:Enum,ed:Enum,rev:boolean)

	-- this is the percentage value we interpolate over
	local nv = Instance.new("NumberValue");
	nv.Value = 0; -- set initial, maybe redundant but let's make sure!
	
	local TimeTable={}; -- this is where we store the percentage values
	TimeTable[#TimeTable+1] = nv.Value; -- set the first index since any change will skip the first value
	
	-- connect an event to fire every time nv is changed by the Tween we create below
	nv.Changed:Connect(function(Progress)
		TimeTable[#TimeTable+1] = Progress; -- store the progress between 0 and 1
	end)

	-- set up the Tween to interpolate nv between 0 and 1 over time t using whatever Easing we choose (every change will be posted to the connected event defined above)
	local tweenInfo = TweenInfo.new(t or 1, es or Enum.EasingStyle.Linear,ed or Enum.EasingDirection.InOut,0,rev or false,1); -- there is a delay of 1 second in the last parameter here because if this function is run in an empty place on initialisation then often the code will fire the Tween before the server replicates to the client in time meaning some time-steps will be missed
	local tween = game.TweenService:Create(nv,tweenInfo ,{Value=1});

	-- play the Tween, wait for it's completion and destroy as required...
	tween:Play();
	tween.Completed:Wait();
	tween:Destroy();
	nv:Destroy();
	tweenInfo = nil;

	-- our return value is a table containing percentages of the Tweens progress
	return TimeTable;
	
end

local x = makeTimeTable(1); -- make a percentage table over 1 second for x value
local y = makeTimeTable(1); -- make a percentage table over 1 second for y value
-- do whatever you want with the percentages in the timetable
-- if the easing style is the same for both x and y then both tables will include the same number of indices
-- so we can safely iterate one and index the other
for index, value in pairs(x) do
	local vec2 = Vector2.new(value,y[index]);
	-- use vec2 as you wish...
end

Here is an example video using the same principle on multiple workspace models applying random Easing styles on both position and rotation using the same code as above.

robloxapp-20230514-2342557.wmv (5.6 MB)

2 Likes

seems to be working perfectly. thanks!

1 Like

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