Designing a custom animation rig setup

I am able to click on the head that is supposedly attached correctly using Motor6Ds (otherwise why would it show up in the top left), but I am not able to change its rotation for the animation.

doganimationrotate

I saw this post
but everytime I try to add motor6Ds to the now unanchored parts that need it, the dog model becomes deformed (mesh parts)
image
This example is when I added a Motor6D to the HRP to connect it with the torso of the dog model.

Not too experienced with custom rigs but are any of the parts besides the HumanoidRootPart anchored?

1 Like

This happens to me when some parts are welded to anchored parts…
Try lift the dog off ground, only have the rootpart (humanoidrootpart) anchored, save and restart studio and try again.

2 Likes

Let me see your rig editor thing please

Like @GammaShock said, you should have all parts inside the model unanchored except for the HumanoidRootPart. Also, check to make sure none of the parts are welded to anchored parts as well.

2 Likes

What is the proper way to link up all the Motor6D joints without the model “spazzing” out?

What I did in studio was

  • Copy the model into a new place
  • Unanchor all the parts in the model with the exception of the HRP
  • Copy in a Motor6D into the Torso
  • Set the Part0 to the dog’s head part
  • Set the Part1 to the torso

As soon as I set the Part1, the head changes to current

And if it’s not connected to the HRP first, head to torso first, still same thing

The HRP is the only part anchored


You need to set the C0/C1 of the Motor6D as you would set a weld.
DaMrNelson made a pretty good character rigging plugin, I’ll try to find a link to it.

6 Likes

Thanks for his name, found it :smiley:

2 Likes

No problem, happy to help!

3 Likes

Did you do these before or after setting C0/C1? Did you set C0/C1 at all?

C0 describes the offset from Part0. C1 describes the offset from Part1. As soon as you set Part0 and Part1, their positions are updated according to C0 and C1.

Here is some Lua pseudo-code to simulate what’s going on. It’s more complicated internally, but this gets the idea across:

-- on Part0 or Part1 change...
if Part0 and Part1 then
	Part1.CFrame = Part0.CFrame*C0*C1:inverse()
end

Here is how C0 and C1 relate:

Part0.CFrame*C0 == Part1.CFrame*C1

Part0.CFrame*C0*C1:inverse() == Part1.CFrame

Part0.CFrame == Part1.CFrame*C1*C0:inverse()

Make sure you’re setting your C0 and C1 before you set Part0 and Part1. The animation editor will rotate your part around where C0 and C1 meet (i.e. Part0*C0).

Some ways to set C0/C1

A quick way to set C0/C1 is to do Motor6D.C0 = Part0.CFrame:toObjectSpace(Part1.CFrame). This will keep Part0 and Part1 in the same place and put the move/rotate center at Part1’s center.

Similarly, Motor6D.C1 = Part1.CFrame:toObjectSpace(Part0.CFrame) will keep the parts in the same place and put the move/rotate center at Part0’s center.


If you want to change where the move/rotate center is located, you can use attachments. This is how normal humanoid characters work now; see BuildRigFromAttachments.

An attachment in your Part0 can act as your C0, and an attachment in your Part1 can act as your C1. The CFrame property of the attachments will match up perfectly with the C0 and C1 properties of the Motor6D.

Here’s some example code. You can run this in the command bar if you use attachments. I have a system to load/unload models from characters while animations are running, and it uses attachments and very similar programming.

local selection = game.Selection:Get()
local motor6d, attachment0, attachment1 = selection[1], selection[2], selection[3]
motor6d.Part0, motor6d.Part1 = nil, nil
motor6d.C0 = attachment0.CFrame
motor6d.C1 = attachment1.CFrame
attachment1.Parent.CFrame = attachment0.Parent.CFrame*motor6d.C0*motor6d.C1:inverse()
motor6d.Part0 = attachment0.Parent
motor6d.Part1 = attachment1.Parent
game:GetService("ChangeHistoryService"):SetWaypoint("Update Motor6D C0/C1")

If you use this, you’ll probably want to start furthest down the tree/extremities and work towards the base, as this teleports parts to the proper location.

If you start from the torso, once you set up the arm, it might get separate from the paw, making it hard to work with.

If you set up the Motor6Ds for the “external” parts first (e.g. eyes, paws), then those will teleport when you set up the “middle parts” (e.g. head, arms). This will be easier to work with.


Alternatively, try one of the animation rigging plugins. I imagine that’s a lot easier, but I’ve never used one. I figure that the internals of how they work is good to know regardless, and might help you if you start adding/removing parts dynamically or something.


5 Likes

Much like setting a primary part using the click system Roblox built in, I thought the same could be done with Motor6Ds

The same can be done, it just doesn’t change the C0/C1, you have to do that manually using a script, the command bar, or a plugin

edit: It automatically moves the part to its designated C0/C1, which, when you create the Motor6D, is C0 of CFrame.new(0,0,0) and C1 of CFrame.new(0,0,0) by default

1 Like

It technically works, because it does set the Part0/Part1, but since your C0/C1 is set to “no offset” (CFrame.new(0, 0, 0)), your parts are moved such that there is no offset (neither positional nor rotational) between them.

You could set C0/C1 by script first, then set Part0/Part1 from the Properties window, but that would be a bit silly. You might as well set both at the same time to streamline the process.


Constraints/Attachments work a lot like the old JointInstances (Welds, Motor6Ds, etc.). Instead of setting C0/C1 directly, you set Attachment0/Attachment1, which boils down to a CFrame property and an easy-to-use interface in Studio. Welds and Motor6Ds were from way before Roblox tried to make it so easy to work with. Hopefully Roblox provides an updated, easier-to-use animation system using Constraints and Attachments sometime soon!


This gives me an idea, though: It would be totally possible to make Motor6Ds and Welds modify-able with a plugin: we can check if a Motor6D is selected using the Selection service, and change what type of “tool” is displayed using Plugin:GetSelectedRibbonTool. That could make Motor6Ds just as easy to modify as Attachments!

4 Likes