I am supposed to make a door that can be tweened open.
For some reason the parts of the door do not stick with the rootpart, even though they are all welded together.
How do I make this work?
Are you able to provide a repro of your door model? Your welds may not be set up properly or you may have the other parts anchored which is causing this issue. Alternatively, you can redo your door and tweening methods according to the tutorial I wrote on model tweening.
Try switching to WeldConstraints or Motor6D, unanchoring all parts except the root and tweening it again. Regular welds are rigid and are meant to hold things firmly in place.
I’m pretty sure your issue is that welds get destroyed when the position/orientation is set on the rootpart.
Instead of tweening Orientation and Position, tween CFrame.
local TweenService = game:GetService("TweenService")
local part = script.Parent
local Info = TweenInfo.new(
1.5,
Enum.EasingStyle.Quint,
Enum.EasingDirection.Out,
0,
false,
0
)
local Goals = {
CFrame = CFrame.new(-126.568,4.5,1.592)
*CFrame.fromOrientation(0,math.rad(115.9),0)
}
local tween = TweenService:Create(part,Info,Goals)
wait(2)
tween:Play()
Basically, for lack of better phrasing, TweenService does not support models/welds natively. When you apply a Tween to a models’ PrimaryPart, the Tween doesn’t follow the rules of welds.
The Solution:
The solution to this problem is creating what’s called a dummy value. Hopefully you’re familiar with CFrame values, string values, number values etc. To successfully Tween your door model, you’re going to want to use a Dummy Value.
Create a CFrame Value
Set the Value to the starting CFrame of the door.
Create a Tween that tweens the newly created CFrame value. It should look something like this…
local tween = TweenService:Create(cframeValue, TweenInfo.new(...), {Value = WantedCFrame})
Before you play you play your tween, you want to make a new connection. Connect a function to the CFrame values .Changed signal.
cframeValue.Changed:Connect(function(newCFrame)
Now, everytime the CFrameValue is changed from the Tween, this function will be called. When this happens, we want to set the position of the door to the newPosition
To set the position of the door model, you’re going to want to set the PrimaryPartCFrame of the model.
doorModel:SetPrimaryPartCFrame(newCFrame)
Gotchas:
This isn’t the most “elegant” way to tween a model
If your model does not have a PrimaryPart, this will error
This does create a new CFrame value everytime you tween, but is removed after the tween is completed
Using CFrame values yields the chance for the other parts of the model to become slightly mis-aligned after many Tweens. If you don’t plan on tweening the door many times, and or don’t care about the change of slight mis-alignment, It’s easier to use this method.
So, our final code may look something like this. I heavily commented so you can fully understand what’s going on
local tweenService = game:GetService("TweenService")
local doorModel = workspace["Wood Crate"]
local function tweenModel(model, targetCFrame, tweenTime)
--Create the dummy CFrameValue
local cframeValue = Instance.new("CFrameValue")
cframeValue.Parent = model
--Set the value of the CFrameValue to the starting position of the door
cframeValue.Value = model.PrimaryPart.CFrame
--Create tween
local modelTween = tweenService:Create(cframeValue, TweenInfo.new(tweenTime), {Value = targetCFrame})
--Create connection to .Changed singal
cframeValue.Changed:Connect(function(newCFrame)
model:SetPrimaryPartCFrame(newCFrame)
end)
--Create connection to .Completed signal (when then tween is finished playing)
modelTween.Completed:Connect(function(playbackState)
if (playbackState == Enum.PlaybackState.Completed) then
cframeValue:Destroy()
end
end)
--Play tween
modelTween:Play()
end
I don’t recommend doing this at all. I actually dedicated a whole section in my above linked tutorial to talk about this and why it’s not a particularly ideal solution. Tweens do support welding, there’s no reason for them not to.
Here’s a chunk out of the thread discussing the use of SetPrimaryPartCFrame:
And you can see a ton of complaints with the function with a quick search on Platform Feedback with just the method’s name:
The misalignment isn’t slight. Floating point imprecisions build up to the point where models get torn apart fully and look like an utter wreck. Depending on how many times you tween, you can find yourself in this position as well. Better to steer clear of an avoidable problem than to ignore it.
This is why I made sure to include a Gotcha section clearly stating the ill-effects of using this method. It’s a spotty method but one that can be used.