Pass a parameter into a tween?

Hey guys, new to scripting here I am trying to make a door large door that will open on a chat command which as of now is working, however im just trying to really get tweens down so I want the tweens to cancel even during the opening/closing process by getting the distance traveled using .magnitude as you can see in the script. Sorry for the mess, but what I have found is the tween happens instantly because the time is 0, so I was wondering if there was a way to pass a parameter into the tween because when I try putting the value in the if then statement it will not update. Sorry for the messy code, I just want to get all this scripting stuff down :slight_smile: thank you

local door = script.Parent
local tweenService = game:GetService("TweenService")
local timetotake = nil

local tweeninfo = TweenInfo.new(
	timetotake,
	Enum.EasingStyle.Linear,
	Enum.EasingDirection.In,
	0,
	false,
	0
)

print(((door.Position - Vector3.new(57, 0.5, 17))/3).Magnitude)

local doorOpen = tweenService:Create(door,tweeninfo,{Position = Vector3.new(57,0.5,17)})
local doorClose = tweenService:Create(door,tweeninfo,{Position = Vector3.new(27, 0.5, 17)})

game.Players.PlayerAdded:Connect(function(player)
	player.Chatted:Connect(function(msg)
		if string.lower(msg) == string.lower("Open Door") then
			timetotake = ((door.Position - Vector3.new(57, 0.5, 17))/3).Magnitude
			doorOpen:Play()
		elseif string.lower(msg) == string.lower("Close Door") then
			timetotake = (door.Position - Vector3.new(27, 0.5, 17)).Magnitude
			doorClose:Play()
		end
	end)
end)

Please do not ask people to write entire scripts or design entire systems for you. If you can’t answer the three questions above, you should probably pick a different category.

Hi!

What you are trying to do is completely reasonable and would be very useful if it was possible, but is unfortunately not. Once the TweenInfo is set, you can’t change it’s set properties, unless you define them again. If it’s necessary, you can of course make some exceptions and create new tweens every time. You will be just fine with that, although that is not the best practice, at least not when the matter is about large amounts of new tweens on each function call.

Here is your script, which is in fact not messy at all :slight_smile:.

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

local DURATION_OPEN = (door.Position - Vector3.new(57, 0.5, 17)/3).Magnitude
local DURATION_CLOSE = (door.Position - Vector3.new(27, 0.5, 17)).Magnitude

local tweenInfo_open = TweenInfo.new(
	DURATION_OPEN,
	Enum.EasingStyle.Linear,
	Enum.EasingDirection.In,
	0, false, 0
)
local tweenInfo_close = TweenInfo.new(
	DURATION_CLOSE,
	Enum.EasingStyle.Linear,
	Enum.EasingDirection.In,
	0, false, 0
)

local doorOpen = TweenService:Create(door, tweenInfo_open, {Position = Vector3.new(57,0.5,17)})
local doorClose = TweenService:Create(door, tweenInfo_close, {Position = Vector3.new(27, 0.5, 17)})

game:GetService("Players").PlayerAdded:Connect(function(player)
	player.Chatted:Connect(function(msg)
		if string.lower(msg) == string.lower("Open Door") then
			doorOpen:Play()
		elseif string.lower(msg) == string.lower("Close Door") then
			doorClose:Play()
		end
	end)
end)

I made my own function for tweening that is very easy to work with:

local TweenService = game:GetService("TweenService")

function tween(object, info, property)
	local tween = TweenService:Create(object, info, property)
	tween:Play()
	if info.RepeatCount ~= -1 then
		delay((info.Time * (info.RepeatCount + 1)) + 1, function()
			tween:Destroy()
		end)
	end
end

Instead of creating multiple variables for tweening and then playing the tween, you can just simply do the following with this function after inserting it into your code:

tween(
    part, --The instance you want to tween
    TweenInfo.new(1), --The tween info used
    {Size = Vector3.new(5, 5, 5)} --The property you want to tween to
)
1 Like

Thank you all this is very helpful and you were very kind! It is interesting to note that tweens can not be updated I will remember that. Thank you again for the responses I will be trying all of this myself!

1 Like

Glad we could help!

Alternatively, you could rely on Lerp. Linear interpolation is a mathematical term to describe a function used to construct a new point between two points, or a value between two values, according to the given third parameter called alpha. Alpha is usually seen as “t” variable in the formula. I usually imagine t parameter as time interval ranging from zero to one seconds. Function is parameterized, with a parameter being a variable, and parameters a and b being constants.

x = a + (b - a) * t ; t = [0, 1] 
-- or
x = (a * (1 - t)) + (b * t)

Now, you can find many uses of this. Compared to tweens:

  • linear interpolation doesn’t require any use of Roblox services (not saying that they are not great). Because it is a function, all we need to do is call it. Roblox provides us with a built-in :Lerp(end CFrame, alpha), which saves us time so we don’t need to write the formula ourselves,

  • linear interpolation outputs a less smooth result. Nothing can compare to TweenService in Roblox engine environment. It is based on loops, which have their limitations,

  • interpolation is, as the name suggests, exclusively linear, and the functions lack the possibility to (easily) configure behaviour as opposed to tweens and TweenService. Easing style is limited to linear, and there is no easing direction to be set,

  • linear interpolation is very useful when we require a smooth number increment. Tweens are limited to properties, so they can’t be used on numbers inside scripts. The only way to use TweenService on a number is to create a new external value outside the script (for example in a separate folder in workspace), and tween the property they store. Linear interpolation also works with vector values.

Finally, here is the script. You will have to change values, because vector values in the script are modified to fit the example. In this case, I decided to write Lerp function manually.

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

local is_running = false -- is interpolation already running?

local function Lerp(startCF, endCF, _duration)
	is_running = true; wait(0.1)
	is_running = false
	local i = 0
	repeat
		door.CFrame = startCF:Lerp(endCF, i)
		i += (RunService.Heartbeat:Wait()/_duration)
		-- exit the loop if function is called again
	until i >= 1 or is_running
end

game:GetService("Players").PlayerAdded:Connect(function(player)
	player.Chatted:Connect(function(msg)
		if string.lower(msg) == string.lower("Open Door") then
			local duration_open = (door.Position - Vector3.new(-50,0,0)/3).Magnitude
			Lerp(door.CFrame, door.CFrame + Vector3.new(-50,0,0), duration_open)
			
		elseif string.lower(msg) == string.lower("Close Door") then
			local duration_close = (door.Position - Vector3.new(50,0,0)).Magnitude
			Lerp(door.CFrame, door.CFrame + Vector3.new(50,0,0), duration_close)
		end
	end)
end)
1 Like

Wow ok so that first section you wrote out, I am completely lost by if im being honest. Like I don’t even know what half of the syntax in that means. Although I see where lerp and tween cross paths in the sense that it just moves from point a to point b. But from what im seeing, using lerp might be more efficient when you are trying to animate something on the go, whereas a set animation might work better with tween, being that it looks better and is more smooth? I’m interested in where and why I would use the two and when you would suggest one would work better. thanks again this is useful stuff!