Is TweenService the only way to do this?

Hi. I really need some help. I’d like to know if this is possible or not without using TweenService.

  1. What do you want to achieve? A more convenient way of transitioning parts without using TweenService.

  2. What is the issue? Technically question 1, except I have no idea of how to transition parts without using TweenService.

  3. What solutions have you tried so far? I’ve tried many different functions and so on, none of them work.

Alright, so here we go. If you know about TweenService (which hopefully you do), you know that code samples many look like this:

local TweenService = game:GetService("TweenService")

local Info = TweenInfo.new(1, Enum.EasingStyle.Linear, Enum.EasingDirection.In) -- And many more that you can add here.

local Goal = {}
Goal.Position = Vector3.new(39.435, 12.345, 93.102)

local Object = game.Workspace.Object
local Tween = TweenService:Create(Object, Info, Goal)

Tween:Play()

Tween.Completed:Wait()
Object:Destroy()

But I’d like to know if there are other ways to use this “Goal” method. For example, here’s a good example of what I want.

local Goal = Vector3.new(350.239, 43.849, 10.239)
local Object = game.Workspace.Object

while wait() do
	Object.Position = Goal
end

However, this won’t work because it automatically teleports to the specified Position instead of slowly making its way toward that position. I know I know you’re going to say for loops would help in this case. Well, yes, but it’d take tons of precision for that kind of loop to make the object reach the exact specified position.

local Goal = Vector3.new(350.239, 43.849, 10.239)
local Object = game.Workspace.Object

for i = 1, 350 do
	Object.Position = Object.Position+Vector3.new(3, 0.2, 0.025)
	task.wait()
end

This will not help me reach the exact position specified. Instead, it will either go over the specified position, or it will be too far away from the position specified. Please, if you have any ways that I can make the part transition to the specified position without TweenService (Because TweenService limits quite a few things, such as Tweening the specified part only, even though another part can be welded to it with a WeldConstraint, and so many more issues that would make this topic a completely different topic.), then I’d be very grateful.

The only other way to move things smoothly is with loops and linear interpolation, you can have it not go over the desired goal if you store the start position and the end position before running the loop like this:

local Object = game.Workspace.Object
local Start = Object.Position
local Goal = Vector3.new(350.239, 43.849, 10.239)


for i = 1, 350 do
     local Alpha = i/350  --will make it so when the loop reaches 350 it returns 1 lerp takes a value from 0-1  to define the progress 
	Object.Position = Start:Lerp(Goal,Alpha)
	task.wait()
end

If you’d like it to not yield the current thread you can use a task.spawn() to wrap it and make it a function so it’s easier to use

Made this function so it looks a bit more like tween

local Object = game.Workspace.Object
local Start = Object.Position
local Goal = Vector3.new(130.27, 7.994, 171.78)
local Goal2 = Vector3.new(101.27, 12.994, 171.78)
local LerpTable = {}


function CheckTableReturnIndex(Object)
	for num,v in pairs(LerpTable) do 
		if v[1]==Object then return num end 
	end
	return nil 
end

function HandleLerp(Object,Start,End,Amount,Timer,Overlap)

	local Data = table.insert(LerpTable,
		{
			Object,
			true
		})

	local Index = #LerpTable
	local Data = LerpTable[Index]
	Data[3] = function()
		for i = 1, Amount do
			if not Data[2] then break end 
			local Alpha = i/Amount
			local Pos = Start:Lerp(
				End,
				Alpha)
			Object.Position = Pos
			task.wait(Timer)
		end
		local Found = CheckTableReturnIndex(Object)
		if Found then 
			LerpTable[Found] = nil 
		end 
	end 

	local Found = CheckTableReturnIndex(Object)
	if Overlap and Found~=Index then 
		LerpTable[Found][2] = false 
	end 
	
	task.spawn(Data[3])

end

task.wait(3)
print'go'
HandleLerp(workspace.Object,Start,Goal,200,0,true)
task.wait(3)
HandleLerp(workspace.Object,Start,Goal2,100,0,true)
1 Like

May I ask, what is your reason for not using TweenService?

What I normally do without using TweenService is that I create an if then statement. It’s not accurate, but it’s (one of) the most accurate way.

while true do
       Object.CFrame = Object.CFrame+Vector3.new(3, 0.2, 0.025)
       task.wait()
if Object.Position <= Goal then -- or vice versa (whatever you desire with the comparable signs)
   break
end
end

It only Tweens one part, which can be a big oof if you have welded other parts to it. And it’s sometimes very frustrating to use, especially when dealing with the Completed functions.

Theres a lot more ways to do it so you should specify the requirements further. Ex you can use PID and Springs to simulate it physically with custom acceleration not tied to the roblox engine.

2 Likes

If you need a straight-line physics based movement like a platform you can also use a PrismaticConstraint. I made up a sample model for another person here in the forums a while ago.

The PrismaticConstraint can be pointed in whatever direction you want by ‘aiming’ the Attachment it uses.

You can also use an AlignPosition (replacement for BodyPosition) to make a Part move from one location to another.

1 Like

Thanks everyone, I will try all of your methods and see which one works for me.

Although this seems like a good method, the part unfortunately has to be unanchored, which I don’t want. So, this method is a :x: for what I want. Thank you for your time though.

TweenService uses something that is known as Interpolation, or commonly known as Lerp, which can be in multiple forms.

Its possible to do this, but other methods would likely be slower, and less efficient than Interpolation.

1 Like

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