Best way to animate welded models

I’m currently animating a semi-complicated tank model. It’s welded together with weld constraints, and is moved by pivoting the primary part of the model (the hull).

The issue arises when I wish to turn the turret. Turning the turret rotates the entire tank, which is not my desired behaviour. My current solution is to disable the weld constraint between the turret and the hull, rotate the turret, then re-enable the weld constraint.

This solution is really simple, and the way I structure my models there should be at most one weld constraint holding two parts together. Of course, this solution feels quite hacky. Is there a better way to do this?

2 Likes

For BaseParts that you wish to hold together but manipulate their relative location via setting CFrame use a Weld. You can changet the C0 and/or C1 property to “animate” the turret.

I was under the impression that Welds were depreciated/worse for performance. Is this true?

I also find it incredibly annoying when using welds, as my parts all snap into each other and I have to recreate the model. I’m not sure how to avoid this behavior.

1 Like

Short answer: No, Welds are not deprecated.

The difference between a Weld and a WeldConstraint is that a Weld maintains relative CFrame between two BaseParts based on C0 and C1 properties (both CFrames relative to the Part0 and Part1 property of the Weld, respectively). A WeldConstraint, on the other hand, maintains a relative CFrame between two BaseParts based on the initial relative CFrames of the two BaseParts when the WeldConstraint’s Part0 and Part1 are set (in other words the relative offset is determined once both these properties are non-nil) and cannot be (easily) manipulated later. When you wish to manipulate/change the relative offset between two BaseParts, this is where Welds come in handy because you can change the C0 (offset relative to Part0) and C1 (offset relative to Part1) as you wish.

Additional brief history

The Weld class existed long before any of the “x-Constraint” classes / physical constraints (the predecessor was the BodyMover base class). The classes descending from BodyMover are now deprecated in favor of the classes descending from Constraint which includes both “Mover Constraints” (AngularVelocity, AlignPosition, AlignOrientation, etc.) as well as “Mechanical Constraints” (BallSocketConstraint, SpringConstraint, RopeConstraint, etc.).

Welding for Animation/AnimationTrack

One other consideration is that if you intend to animate BaseParts via an Animation/AnimationTrack then you should use a Motor6D instead. This class is similar to a Weld, however includes an additional property “Transform” which is used internally by the animation system.

3 Likes

The behavior you’re experiencing where “parts all snap into each other” is because a newly created Weld has its C0 and C1 properties both set to a blank CFrame (what you get from the line CFrame.new(0,0,0)). You could fix this either by not generating the welds at runtime or by calculating the offset between the BaseParts you wish to weld and setting the C0 or C1 property to offset them to their pre-welded position and orientations.

I see. Thanks for the information regarding the welds!

I’m not sure how your solution to prevent snapping parts will work. My issue is that this occurs when I’m rigging my model - I’m not creating any welds at runtime. I do know how to recreate the positions by setting the C0 and C1 property, but I find it incredibly tedious as I have to do this manually.

Edit: Dumb little me forgot that I only had to use welds for the parts that actually needed animating. Thanks for the help!

Ohh ok, gotcha. Yeah creating welds in studio definitely is tedious. Thankfully that’s where plugins or the command bar come in handy. There’s loads of plugins out there that will automatically create a Weld (not WeldConstraint) between two BaseParts and set the C0 or C1 property such that the weld maintains their current relative offset. At the core they’re doing some sort of operation like this (written so that you could run this in the command bar by changing the paths for variables pa and pb):

local pa = workspace.PartA
local pb = workspace.PartB
local weld = Instance.new("Weld", pa)
weld.C0 = pa.CFrame:ToObjectSpace(pb.CFrame)
weld.Part0 = pa
weld.Part1 = pb

Yeah, thanks for the suggestion! I searched for a good plugin to do this and it turns out I already have RigEdit. Pretty neat.

Huh. Upon further research, my initial method is apparently the intended one. Both solutions work and I guess there may be different use cases, but for me this solution is easier to implement.

Still, thanks for all the help!

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