Any way to tween a model via TweenService?

BEFORE BUMPING: THE WELD METHOD HAS ALREADY BEEN SHARED. (07.11.2022) There’s been a few times where new posts have mentioned a method already posted, especially the weld method. Please see the edit below which has a link to a tutorial on tweening models or post #2 for a summary of how to perform the method!

EDIT: I see this post is still getting linked. Please use the new method I’ve devised and posted on Community Tutorials as opposed to this. It is available here. Solution has been changed for this purpose as well.


I know you can tween parts but tweening a model is a little difficult. My aim is to use TweenService to tween a model.

In the past, I’ve tried:

  • Searching the forums and using the methods listed, which do not answer my question or fit what I want
  • Welding unanchored parts to an anchored part and tweening it, only the part moved and not the items welded
  • Using any of the Model CFrame methods, including PrimaryPart, which completely failed unless there’s something I’m missing here and didn’t do it properly
6 Likes

Have all your unanchored parts welded to a main anchored part, then use tween service on that weld C0 value to move it relative to the main anchored part.

Edit: @edenojack Edenojack is correct with the Motor6D so heres a Demo I wrote explaining this method:

32 Likes

Welds don’t update their position when the part they’re cframed to an anchored part.
Motor6D’s do though.

2 Likes

I normally use TranslateBy to make a similar effect for a model.

if the model doesn’t have too many parts (so that it wont cause lag) you can use something along these lines

local TweenService = game:GetService("TweenService")
local Model = workspace.Model
local Info = TweenInfo.new()
local PrimaryPartDestination = Vector3.new()

for i,Part in pairs(Model:GetChildren()) do
local Tween = TweenService:Create(Part,Info,{CFrame = CFrame.new((Part.Position-Model.PrimaryPart.Position)+PrimaryPartDestination)})
Tween:Play()
end

there might be a better way to do it, but this is what i’ve used

9 Likes

Mind that all your parts will go unrotated by this.

There is quite a lack of tweening multiple instances with TweenService, too, but that’s more of a feature request :thinking:

2 Likes

Thing is, with TranslateBy, you have all this math involved and it only offers linear tweening lest you want to do even more math or search for open source tween style modules and extract the math from them (which is as much a pain due to their disorganization/cluttering/how much text there is filling the screen/etc).

I’m a lazy person and am looking for a simple solution to tween modules via the TweenService or usage of a module named RBXAnimator by @FriendlyBiscuit.

There’s little to no math put into it. I can be wrong, probably just my opinion, but I find it’s just simple integrated algebra equations and loops put together in order to do so. If you don’t want to put in the effort then that’s fine but the work you put in to get the end result that you’re looking for will pay off.

You can use a dummy object and pass the changes made to the model itself.

local tweenService = game:GetService("TweenService")
local info = TweenInfo.new()

local function tweenModel(model, CF)
	local CFrameValue = Instance.new("CFrameValue")
	CFrameValue.Value = model:GetPrimaryPartCFrame()

	CFrameValue:GetPropertyChangedSignal("Value"):connect(function()
		model:SetPrimaryPartCFrame(CFrameValue.Value)
	end)
	
	local tween = tweenService:Create(CFrameValue, info, {Value = CF})
	tween:Play()
	
	tween.Completed:connect(function()
		CFrameValue:Destroy()
	end)
end
60 Likes

unanchor and weld the parts then tween the center part.

1 Like

This is by far the most effective method in my opinion, does anyone know what the downside of this is (i.e. possible lag or something)? Honestly I believe this would be the ideal/better solution if not.

The only problem I’ve ran into, as well as something others have asked me for guidance on, is that the solution I’ve currently proposed (I basically turned this response into a whole tutorial) currently has issues when it comes to tweening nested assemblies. For example, the door handle on a door.

Minor scale issue that can be resolved with some investigation or help, but otherwise yes, I do agree in that this is a very effective method. Your downsides are basically limited only to practices involving TweenService (e.g. use the client not the server for smooth tweens) and if you have any explosions that destroy joints in your game, then physics simulation as well.

I otherwise highly recommend the weld-and-tween-a-root route when approaching this problem.

1 Like

Hello!
Sorry for bumping this topic, but for those that want an alternate solution to tweening a model without using any CFrame values, you can use my solution for this that uses tweenService:GetValue:

local runService = game:GetService'RunService';
local tweenService = game:GetService'TweenService';

local tweenModelCFrame = function(Model, tweenInfo, endCFrame)
	local tweenTime = tweenInfo.Time;
	local easingStyle = tweenInfo.EasingStyle;
	local easingDirection = tweenInfo.EasingDirection;

	local startCF = Model:GetPrimaryPartCFrame();

	local timePassed = 0; 
	local Connection;

	Connection = runService.Stepped:Connect(function(Time, Delta)
		timePassed = timePassed + Delta;
		if timePassed > tweenTime then
			Connection:Disconnect();
			Connection = nil;
			return;
		end;

		Model:SetPrimaryPartCFrame(startCF:Lerp(
			endCFrame, 
			tweenService:GetValue(
				timePassed / tweenTime,
				easingStyle, 
				easingDirection
			)
		));
	end);
	return Connection;
end;

Example usage would be like so:
tweenModelCFrame(yourModel, TweenInfo.new(...), CFrame.new(...)).
This returns a RBXScriptConnection which you can disconnect when you like :slight_smile:

1 Like

This method avoids the use of a CFrameValue but still involves SetPrimaryPartCFrame which is a problematic function in itself. Even if you drop the ValueObject from the system, I still don’t recommend using this code because of that one function. It would be better if you wrote your own custom SetPrimaryPartCFrame function to manually offset parts from a root.

Refer to Introduction to Tweening Models, a tutorial I wrote out of getting more familiar with how to tween models. It has a section explaining why SetPrimaryPartCFrame is bad.

Sorry for bumping this topic, but there is a way better solution for this. It doesn’t require any welding or any primary part. You simple just set the pivot of the part. Here’s an example:

local TweenService = game:GetService("TweenService")

local model = workspace.Model -- put your model here
local connections = {}

local cFrameValue = Instance.new("CFrameValue")
local tween = TweenService:Create(cFrameValue, TweenInfo.new(0.5), {
    Value = CFrame.new(0, 1, 0) -- put your CFrame here
})

connections[#connections + 1] = cFrameValue:GetPropertyChangedSignal("Value"):Connect(function()
    model:PivotTo(cFrameValue.Value)
end)
connections[#connections + 1] = tween.Completed:Connect(function()
    cFrameValue:Destroy()

    -- disconnect all connections
    for _, connection in pairs(connections) do
        connection:Disconnect()
    end
end)

tween:Play()
2 Likes

When I’m tweening a Model, I will first select a PrimaryPart and then weld the model toggether with an Plugin. Then you just gotta tween the PrimaryPart and the things around it are also moving.

You’re a little late with the bump there – this information was shared in post 2 and there’s also a link in the OP including a tutorial on how to tween models which includes the welding method (though now it’s probably better to be using pivots for this unless you require intricate movement!).

2 Likes

Well the topic was tweening and not instant model teleportation so PrivotTo() doesn’t work.
Didn’t see it is 5 years old :person_facepalming: