What's a better way I could Tween a large model?

I’ve known how to Tween models for a while, however I’m aware that I’m definitely not doing it properly. I’ve decided to try to change the way it works as I’m now building a tram which moves between 3 stations on a time delay. I have the script working, however I’m aware that the model Tweening function is bad practice.

Currently, I create a CFrame value, parent it to the model’s primary part, create a :GetPropertyChangedSignal(“Value”) hook to do :SetPrimaryPartCFrame every time it is triggered, then Tween the primary part and then destroy the CFrame Value once the tween is complete. Now, it works, however it’s probably the worst way I could have done it, and now that I’m trying to move a larger model I need a better, less laggy way of doing it.

So far, I’ve thought of maybe welding the model’s descendants to the primary part (if they are a union operation, mesh part or part) and then Tweening the primary part as normal, however I’m unsure as to whether this is the best way forward?

[ Bear in mind the model has doors which need to open/close! ]

If anybody has a better way I could do this, I’d really appreciate it. Thanks!

Here’s my current script:

local function TweenModel(Model, ToGo, Time)
    local TS = game:GetService("TweenService")
    local TI = TweenInfo.new(Time, Enum.EasingStyle.Sine, Enum.EasingDirection.InOut, 0, false, 0)
    local TP = {CFrame = ToGo}

    local P = Model.PrimaryPart

    if not P then
        warn("Model needs a primary part in order to be tweened.")
        return end
    end

    local CValue = Instance.new("CFrameValue")
    CValue.Parent = P

    CValue:GetPropertyChangedSignal("Value"):Connect(function()
        Model:SetPrimaryPartCFrame(Model:GetPrimaryPartCFrame())
    end)

    local Tween = TS:Create(P, TI, TP)
    Tween:Play()

    Tween.Completed:Connect(function()
        CValue:Destroy()
    end)
end)
1 Like

I am not sure if this works cause I never tried this but can’t you weld models together and then if you tween one the other ones will move to?

Again I am not sure so correct me if I am wrong.

1 Like

I tried, and yes it worked, however the doors were unable to open. Thanks, though!

The method SetPrimaryPartCFrame is known to drift from the correct value over time. I don’t recall why because this was first discovered by TigerCaptain a few years ago. The preferred method is to weld every part to a primary part and set the primary part’s CFrame directly.

2 Likes

Oh just make the doors it’s own tween then? Like if train stopped open doors.

1 Like

Yeah I know, that’s the reason I want to change the method. My problem is that welding everything locks the doors in the closed position, and to move them I have to revert to the method shown above. The train seems to stay in tact, however?

Would work however the doors comprise most of the train and to have them move, I need the old method. To do this it would render the train useless as the lag would be pretty much the same.

1 Like

Hm, Idk then. You could try using motors. I’m not good with them tho so you would have to look for some tutorials about them.

Edit: You could tween the whole train but use motors for the door, I think it should work, you can try it tho.

1 Like

Looks like it works, however they slowly begin to go out of sync, instead of moving exactly 1 stud for example, they move 0.9-1.1, which slowly offsets the original CFrame and thus the doors begin to move apart or closer to each other.

1 Like

Hm, again I don’t really use motors, you would have to look into this somewhere else.

1 Like

If you’re tweening a tram between stations could you simply use a script to weld the doors to the tram, tween the primary part as discussed in this thread, and then destroy the welds once the tram arrives at the station?
This way the doors would still not be able to open whilst the tram is moving, but they’d be fine when actually at the station. If this is not an acceptable compromise, you could simply calculate the target CFrame for both the tram and the doors and then tween them separately.

2 Likes

This works however creates a lag spike every 30-ish seconds as the welds are created or destroyed. I’ve re-modeled the tram so that it uses a few less parts, and it seems to cause less lag now, and the tween is also much smoother. However, if the game has been running for a while and a few events have been triggered, such as hallways being destroyed (this is a core game), it begins to fall behind on itself again.

Thanks for the help, though!

You shouldn’t be destroying welds for all the part in the tram, just the ones connecting the tram to the door

1 Like

Mostly for large models, I use WeldConstraints.

You’ll have all parts welded to PrimaryPart, then CFrame tween the PrimaryPart, and all of the model would move, there could be better methods but this is what I do.

The best suggestion I could offer you is to use ANIMATION!

Simply rig the model by welding all detail upon a single joint part, (could just be a root part), and then create a simple animation with the path you want, timed how you want.

Animations are way more ideal for this use case compared to tweening, or looping SetPrimaryPartCFrame. They also are very performant, and easy to adjust as needed.

Read into: Using Animations | Documentation - Roblox Creator Hub
Especially the non-humanoid section for more details.

Feel free to ask any questions about specifics, I’d be happy to provide. :+1:

Just be sure to adjust the collision fidelity of the tram to be as simple as needed for performance.

1 Like