Brief Introduction to Tweening Models

tweening

#1

Note: I’m going to be rewriting this tutorial later. The current setup doesn’t look comfortable.

Some context and background to understand the situation and purpose of this thread.

Nearly a year ago, I came to the DevForums to ask how to tween models. I’ve always been a fan of tweening because the fluidity and smoothness is always aesthetically attractive - I used tweens or loops anywhere I could to get that aesthetic appeal. At this point, I only knew how to do it for singular items. Models have always been troublesome for me when it came to tweens, so I posted a thread reaching for help.

Between the time I received a response and now, that thread has been linked and shared over and over, including just a few hours ago. Now the thing is, that method has been discovered as problematic. For this reason, I create this Community Tutorial on tweening models. It will provide commentary on the method and teach a better method to tweening models. This is merely scratching the surface and a starting point, there are many ways you can modify this method or take a different approach.

Yes, I see at the bottom Builder_Boy provided a response. Some people also said something similar. I’m providing a detailed version of those same responses.


So, let’s address the first thing. What is this supposed “frequently-shared” method?

The method that was marked as the solution goes as follows, in bullet points so we both can understand the workflow easily.

  • A dummy object, CFrameValue, is created. This value is set to the CFrame of the model. This dummy object will act as a reference value for applying CFrames to the real object.
  • The Changed signal is connected to. Every time the CFrameValue changes, the model uses SetPrimaryPartCFrame to move the model to that dummy object’s value.
  • A tween is ran on the value of CFrameValue. The code above gets to work.
  • The dummy object is removed when the tween finishes. Anything within the functional scope is garbage collected and we’re all good.

Code:

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

Hey though, that looks fine. What’s the issue?

Through searching and experimentation on topics unrelated to tweening, as well as a response on the thread linked in my introduction, this method actually has a few problems. These are also in bullets.

  • You can’t use this code without a PrimaryPart set on the model. If you attempt to call this method without a PrimaryPart, it’ll throw an error. This will cause the rest of your script to terminate.
  • SetPrimaryPartCFrame actually has float point errors. Though I myself am not sure where it comes into play, I know that the function produces these errors and enough usage of the function will slowly but surely tear your model apart.

Now, as a developer, I like neither of those things. A terminated script? A model that’s lost its original composition? We can’t be having that.

In some cases, you can modify this code to fit your needs. It’s actually a pretty good solution to get started with, but in the long run you’ll want something you can rely on at a fundamental level without the aforementioned issues. So, let’s check something new out.


What can we do to change our approach?

The new approach I applied was actually quite neat. It gets the job done, produces no errors if done right and I can litter the code anywhere I wish, the way I like to script. So, here are the steps.

  1. Create your model however you want. Use your existing model if you have one.
  2. Create an invisible part. This will act as your root.
    • If you intend on tweening the entire model, have the invisible part cover the model in its exact dimensions.
    • If you intend on making a pivot of sorts, make it scale up one way. Image example will be Figure 1 at the bottom of these steps.
  3. Weld all parts to the invisible part. Unanchor every part and set up collisions however you wish. Leave the invisible brick with anchor on and CanCollide off. You must use Motor6D.
    • I use a personal mod of Ozzypig’s Weld Plugin to quickly accomplish my weld work. Instead of using ManualWelds, it’s changed to use Motor6D.
  4. Do your tween work on this invisible part. You’re done!

Figure 1


The neon brick is the pivot. Normally, that would be invisible and the door wouldn’t have any transparency.

In conjunction with Figure 1 (pivotal tweens), here’s some code for reference on how I make them spin open:

-- This code has been edited from its original state. This is not how I normally code.
-- I hope you're still able to follow along, despite that. Code below is an edit by Dr_K4rma.
local ts = game:GetService("TweenService")
local goal = {}
goal.CFrame = Pivot.CFrame * CFrame.Angles(0, math.rad(-90), 0) -- Pivot defined elsewhere
local tinfo = TweenInfo.new(1)
local t = ts:Create(Pivot, tinfo, goal)
t:Play()
t.Completed:Wait()

And just like that, you have yourself a tweened model. Hopefully.

One thing to keep in mind while using this method, before I close off: this method is accomplished by the use of welds. Your models are not safe and items such as explosions, if not configured correctly, can cause your model to be destroyed as explosion objects destroy joints. I recommend only using the Explosion object for effects and handling explosions another way (raycast), or by creating your own explosion aesthetics and hit effects.


Edit time! How did you mod Ozzypig’s Weld Plugin?

Glad you asked, @RuizuKun_Dev. Due to your question, I have edited the thread to direct you to the response I made on how I accomplished a mod of Ozzypig’s Weld Plugin. Now not only have you helped yourself, but you’ve helped others with the same question! Check out the response.


And I suppose we’ve got a nice little model tween tutorial.

I also have nothing else to say. Leave comments or concerns below, or something. :slightly_smiling_face:


Resources

Ozzypig’s Weld Plugin: Here
Personal Mod: Here


TweenService on a model (vector3)
Problem with animating a moving part w/ for & CFrame
Check for part position
#2

Amazing guide, I’ll definitely be using this in the future. In the past I’ve been using reference points then tweening each part of the model individually (uses a lot of unnecessary code), but this seems like a way to finally reduce that code!


#3

How? I installed the plugin doesn’t seem to have an option for what kind of Weld you want to use


#4

“Personal mod”
He modified it to use Motor6Ds instead of ManualWelds.


#5

How do I do that? @colbert2677 ?


#6

Essentially what you want to do is change the source code of the plugin and then push it to your own plugin folder. There’s several ways you can accomplish this, I’ll teach you an easy trick for it.

Keep in mind, this only works because Ozzypig’s plugin source code is open source. Some plugins, when you insert their scripts, are actually closed-source with requireIds. One plugin even inserts a random value and no kind of script at all.

  • Install Ozzypig’s Weld Plugin as linked in the OP. Make sure you know the AssetId of the plugin. In this case, the Id is 148570182
  • Open up Roblox Studio. A blank place will work for this project.
  • Right click Workspace for the context menu and select Insert into from file. Navigate to your Roblox plugins folder. Open up the folder that has the name of the AssetId and insert the model.
    • You can type this in the Explorer address bar to gain access quickly: %appdata%\..\Local\Roblox\InstalledPlugins\148570182
  • Once this is done, you should have the plugin source files in your Workspace. image
  • Open up the Weld model and open the script called Main, the only file in the group.
  • Use the Ctrl + H replace menu and change everything in the script from “ManualWeld” to “Motor6D”. Use image as reference for what it should look like. Hit “Replace All”.
    image
  • Exit the script. Right click on the Model and hit Save as Local Plugin. Give it a name, whatever you’d like. Once the plugin is saved, go to Plugin Manager and disable the installed one.

And thus, you have it.

Edited the main thread to include a quick link to this response as the section before the conclusion.


#7

seems like this can also finish the job


#8

So long as it works for you personally, any kind of plugin, code, etc. that has the capability of creating Motor6Ds and welding parts together will work.

This plugin, given the video tutorial, looks more interactive in it’s setup (specifies what’s the start point, then let’s you select other parts to get welded to it), whereas the plugin in the OP has no dialogues, just straight creation.