Character rigging can often be a complex process that also requires a certain amount of indirection. The purpose of
character rigging is to give a character the ability to move. This is done by first giving the character a set of joint,
which act similarly to the bones in a human skeleton. When these joints are moved, they will deform the mesh of the
character. However, animators do not use these joints to animate. Instead, they will using a set of animation controls
(called "anims" in this course) to control the bones that will deform the mesh. This may seem convoluted, but it allows
a lot of flexibility to give the animator what they need. We will be using the Animation menu set for this project.
This project is split into three parts:
Creating the character skeleton
Creating animation controls (called "anims" in this course)
Creating eye blinks by using blend shapes
Weight-painting the character
Unlike most of what you've done in Maya so far, many of the results of rigging can't be seen in the viewport. You'll
have to use a combination of the Outliner and the Hypergraph editor to see what is really going on. So here are a couple
of tips:
Follow the directions carefully. When rigging, something small, like the order in
which objects are selected is important. You may even want to check off the steps on a printout as you go.
Test, test, test. The controls that are given to the character will be the ones that
animators will be using for hours on end, so keep testing them to make sure that they work as expected.
Below are the rigs that will be used for this assignment:
The Mouse. This tutorial is designed for rigging this character. This
is the required part of the assignment.
The Cat. If you have some extra time and would like to try rigging another
character, try your hand at this cat. It will be extra credit.
For reference, the final joint layout on the cat should look something like this
front view and side view
(similar to the results of steps 3-7 on the mouse).
You will occasionally be using a rigging shelf, called RiggingPlus with scripts created by Jason Scheifer, a superstar
of rigging, throughout the assignment. It already comes pre-packaged in the
production workspace.
Part 1: Creating the Character's Skeleton
First, we have to design the skeleton that will move the mouse. We will start with the spine.
Make sure joints are visible in the Viewport (Show → Joints).
In the Side view, use the Skeleton → Create Joints to create a joint chain along the
spine. Start at the base of the mouse and work up, following the picture below.
TIP: While in the joint tool:
Backspace will undo the last joint.
Enter will complete the joint chain and exit the joint tool.
From the bottom up, name these four joints: root_joint, spine_1_joint,
spine_2_joint, and head_joint. They will appear in the outliner grouped under each other, so
use the + symbol to expand. Having a clear and consistent naming scheme is a great help in rigging since it
allows you to automatically handle certain tasks with scripts.
If the joints appear too big or small, you can adjust their size by going to
Display → Animation → Joint Size... (this only affects how they are displayed, and not any internal structure).
Now we will set up the skeleton for the tail.
Create a three joint chain (3 clicks, 3 joints, 2 bones) from the base of the tail to the tip.
We will now split the chain into 8 segments.
Make sure the first two joints of the chain are selected
Use the "Split selected joint" script from the Rigging shelf
()
to split both joints into 4 segments, which will split the chain into a total of 8 segments.
Rename the joints tail_1_joint, tail_2_joint, tail_3_joint, etc.
This can be done manually, or the "Hash Rename" script
() can help with this:
Select the joints in the order you want them to be numbered
Press the "Hash Rename" script
() button on your
rigging shelf.
Type tail_#_joint into the box and press Enter.
The script will replace the hash mark with a number in the order the joints were selected.
Parent tail_1_joint under the root_joint once you are done.
We will need to create a number of joint chains to control the various parts of the head. The mouth and nose chains
are the simplest and can be created in the Side view.
Create one joint at the base of the jaw and another at the tip.
Name these joints mouth_1_joint and mouth_2_joint.
Repeat for the nose, naming the joints nose_1_joint and nose_2_joint.
Parent these chains under the head_joint.
Now we will create the ear joint chains.
Create a simple joint chain in the Side view from the base of the ear to the tip (2 joints, 1 bone).
In the perspective view, use translate in the negative X direction to move the base
joint to the base of the left ear. The joint chain will still not be completely inside the ear, so rotate the base
joint until the end joint is inside. Do not move the end joint, only rotate the base.
After you have rotated the base joint, select it and go to Modify → Freeze Transformations.
This will eliminate the rotate that you added.
Name these joints left_ear_1_joint, left_ear_2_joint.
Select the base joint and go to Skeleton → Mirror Joints (Options). Mirror across YZ
and have it "Search for:" left and "Replace with:" right in the joints. Click Apply and
you will have a pair of right ear joints that are properly named.
Parent these chains under the head_joint.
Our last set of joints will be for controlling the eyes.
Create a single joint for each eye. To place the joint exactly in the middle of the eye,
we are going to create and then remove a constraint.
Select the eye geometry, then the joint in that order (it may be easiest to select them in the outliner
using Ctrl-click to select multiple objects). Then go to Constrain → Point(Options). Un-check Maintain offset
and click Add.
Delete the constraint that is created under the joint in the Outliner. If it was created under the eye, you
selected the eye and the joint in the wrong order and you will need to use Undo (z) to get the eye back where
it should be. Once the constraint is deleted, the joint should remain in the center of the eye.
Name this joint left_eye_joint and repeat the process for the right eye. Name it right_eye_joint.
Parent these joints under the head_joint.
Part 2: Creating animation controls
It would be annoying if the animator had to select these control joints every single time they wanted to move the tail or any part of the body. They are hard to reach and more often than not,
the animator will probably select the skeleton instead of the control joints. So, we want to separate the animator from using these joints at all. We will give them animation controls
to move the character.
Let's look at the idea behind an animation control. It is basically a handle in 3D space, linked to a certain joint on the skeleton, which an animator can easily grab and move to pose the character.
As a short hand we refer to these control handles as "anims". Note that this in an in-house term, as on different rigs they can be referred to as "cons", "flags", etc.
The overarching concept is the same, however.
For this rig we will be using NURBS curves to create our anims.
Let's start by making an anim for the spine.
Create 1 NURBS circle for the first spine anim.
Name the anim spine_1_anim.
These NURBS curves are parented under what is known as a zero group. Think of these zero groups as a shell that will hold all miscellaneous transform (translate, rotate, and scale) values that will
occur as you move the controls around to get them in the right spot. This will also allow us to align the rotation of the anim with the joint, making the control more intuitive.
But why is something like this important? It doesn't seem like it would be necessary. We need these zero groups so that we have a zero position for our animation controls. It is often useful for
animators to be able to zero out (put 0s in the translation and rotate values) an anim back to its default position. So let's start off with the case where we don't have a zero group.
Let's look at the spine joints that we made earlier.
Let's make a NURBS Circle and call it our spine_1_anim and then align it with the direction of the joint. We then constrain the joint to the control so that we can move it.
However, when we align a control to a joint like this, we get values in the anim's tranform channels.
If we try to "zero-out" (put zeros in the translation and rotation channels) we get a result that we don't want.
We see that the root_joint and the spine_1_joint end up on top of each other, and the rotation of the joints are not in that default position that we had defined earlier.
This isn't useful. Earlier we learned that freezing transforms would give us the ability to set a new default position for an object so let's try that instead.
As we can see, this does what we kind of want it to do. There are not translation or rotation values in the channel box and the rotation of the joints is still in that default
position we decided on earlier. However, if you look at the orientation of the anim, you will see that it had changed. By freezing the transforms of an object, you return its
orientation to World Space.
It doesn't seem like it would really matter if a control is aligned with the orient of the joint, so why do we care so much about it? By allowing the control to be aligned arbitrarily
with world space, it becomes less intuitive for the animator. An animator wouldn't have a good idea of how the control works and they thus might have to counter animate to get some of
the movements that they thought the control had, but didn't.
If the anim is aligned with the joint, it is easier for the animator to do things like move spine_1 up along the angled y-axis. Or if they want to rotate the joint along the z-axis,
they can, and they will know the path of that joint. It's a more intuitive set up.
As we can see, aligning an anim along a joint can give the animator insight to how the control can be used and in certain situations may also assist them in their animation if they
need the controls to move in a certain way.
That's great! Now, since we know we don't want to freeze transforms on the control, but we want a control that is aligned to the joint, let's see what happens when we add a zero group.
We will parent the spine_1_anim to a group called spine_1_zero_grp. We will when move this group and orient it to the joint. In the scene it will look as if nothing has changed.
However, when you look at the Channel Box, you will see that spine_1_zero_grp will now have all of the transform information that we had originally had in the anim itself.
If we use zero groups to hold all of these positioning transforms, our anims will be clean. As you can see, there are no transforms on the anim.
Thus when we zero out a control, it will default to the position we determined would be the default.
Now, let's go over how to utilize these zero groups in our rigs.
In addition to the NURBS circle you made earlier for the spine_1_anim, create 3 more NURBS circles.
Name the anims: root_anim, spine_2_anim, and head_anim.
Create an empty group for each of the 4 anims.
Name the groups: root_anim_zero_grp, spine_1_anim_zero_grp, spine_2_anim_zero_grp, and head_anim_zero_grp.
Parent the anims to their corresponding zero groups.
Parent head_anim under head_anim_zero_grp.
Parent spine_2_anim under spine_2_anim_zero_grp.
Parent spine_1_anim under spine_1_anim_zero_grp.
Parent root_anim under root_anim_zero_grp.
Position the zero groups over the joint they control by:
Select the joint and then the zero group and use a parent constraint (Maintain offset un-checked).
Delete the constraint that was created in the zero group.
If the anim is not aligned with the joint that it controls, rotate the zero group to align it.
We want our anims to also be in a hierarchy so that they will move together in the same space:
Parent the spine_1_anim_zero_grp under root_anim.
Parent the spine_2_anim_zero_grp under spine_1_anim.
Parent the head_anim_zero_grp under spine_2_anim.
Lock and hide all channels except the rotation for the two spine anims.
Lock and hide all channels except the rotation for the head anim.
Lock and hide all channels except for translationa and rotation for the root_anim.
Lock and hide all the channels on each anim zero group.
We will have these anims control the spine through a set of constraints.
Select the root_anim, then the root_joint and use Constrain → Parent (Options) and make sure to create the constraint with Maintain offset checked.
For the other two spine joints and the head joint Constrain → Orient (Options) them to their respective anims with Maintain offset checked.
Test it -- move the root anim, the whole skeleton and tail anims should move with it.
We will deal with the mouth, nose, and ears in a similar manner.
Create 4 NURBS circles.
Name them mouth_anim, nose_anim, left_ear_anim, and right_ear_anim.
Create one zero group for each of the anims.
Parent the anims to their zero groups.
Position the anims near the ears, nose, and mouth of the mouse.
We could make it so these anims are positioned like the spine anims, but they might not be easy to access for the animator. So we will just position them near the joints that they control
and move the pivot of the anim.
We can position them by going into vertex mode (F9), selecting all of the vertices and using the move tool to move them from their original position.
Use Orient constraints (Maintain Offset checked) to allow these anims to control the first joint of these chains.
Lock and hide all channels except rotate for these anims.
Lock and hide all the channels on each anim zero group.
Group all the head anims into a head_anims group.
Select the head_anim, then the head_anims group and go to Constrain → Parent (Maintain Offset checked).
Test - the head anims should follow when you turn the head, each head anim should control the expected joint.
To rig the eyes, we will first need to constraint the eye geometry to the eye joints so that we can see if our eye rig is working.
Select the left eye joint and then the eye geometry. Then use a parent constraint (Maintain Offset checked)
Do the same for the right eye.
Test -- ensure that moving the joint moves the eye -- don't forget to set it back to 0 rotation.
Now when you rotate the eye joints, the eye geometry should follow.
Create two NURBS circles.
Name the anims left_eye_anim, and right_eye_anim.
Create one group for each of the anims.
Name the groups left_eye_anim_zero_grp, and right_eye_anim_zero_grp.
Parent the anims to their groups.
Parent constrain (Maintain Offset un-checked) the groups to the eyes, and delete the constraints.
Move the eye anim zero groups forward so that the circles are out in front of the face.
Create another NURBS circle that will surrounds the other two. Name the circle both_eyes_anim.
Create a group for this anim. Name the group both_eyes_anim_zero_grp.
Parent both_eyes_anim to its zero group.
Position it by constraining it to one of the two eye anims (delete the constraint) and re-shape it.
Parent left_eye_anim_zero_grp and right_eye_anim_zero_grp under both_eyes_anim.
Lock and hide all channels on each of the three eye anim zero groups.
Next up is making the anim controls for the eyes.
Select either the left or right eye anim, then its respective eye joint and go to Constrain → Aim (Options).
Turn on Maintain offset and change the Aim vector to (0, 0, 1).
Do this for the other eye as well.
We want the eyes to move with the head so directly parent both_eyes_anim_zero_grp to the head_anims group.
Lock and hide all channels on all three eye anims except translate.
Test -- make sure the eyes follow when both_eyes_anim is moved, and that each eye anim controls the eyes individually.
Now that we have our basic joints and anims in place for the other parts of the mouse in place, we can start adding more sophisticated control over the tail.
It would be a hassle to control each individual joint in the tail and so we will use an IK Spline to control them instead.
First, we create the curve that the tail will try to follow:
To start, use the CV Curve Tool (found in Create → Curve Tools → CV Curve Tool) to create a curve passing through the tail.
Make sure the Curve degree is set to "3 Cubic" in the Tool Settings. Snap each new CV to a joint in the tail chain using vertex snapping (the v key).
It may be helpful to temporarily hide the body geometry so you don't snap to vertices on either side of the tail.
Check that your curve is straight from the top view (and un-hide the body if you hid it).
Name this curve tail_curve.
Now we will create the actual IK Spline to control the joints.
Go to Skeleton → Create IK Spline Handle (Options) and disable Auto create curve.
Using the tool, select tail_9_joint, then tail_1_joint, then tail_curve. The IK handle will be created as soon as you select the curve.
Name the newly created IK Handle tail_ik_handle. You will not be able to control the tail just yet.
Create an empty group (Ctrl+g with nothing selected) and name it tail_grp.
Directly parent the tail_curve to the tail_grp by selecting the tail_curve, and then the tail_grp before pressing p
Place the tail_ik_handle into this group. Eventually we will place other things associated with controlling the tail in this group.
Create three single joints, snapping them to tail_1_joint, tail_5_joint, and tail_9_joint respectively. You can do this by:
Creating a single joint.
Go into the move tool (press w) and then, while holding down the v key and middle clicking on the mouse, drag over to tail_1_joint.
This will snap it to the tail_1_joint.
Repeat for the two joints that will be at tail_5_joint, and at tail_9_joint.
Name these joints curve_control_1_joint, curve_control_2_joint, and curve_control_3_joint.
Now we will make anims and zero groups for the tail.
Create three NURBS circles. Name the anims tail_base_anim, tail_mid_anim, and tail_end_anim.
Create three empty groups. Name them tail_base_anim_zero_grp, tail_mid_anim_zero_grp, and
tail_end_anim_zero_grp.
Parent the anims to their respective zero groups.
Position the tail anims over the control curves by using parent constraints and then delete the constraint. Tail_base_anim_zero_grp should go over curve_control_1_joint.
Tail_mid_anim_zero_grp should go over curve_control_2_joint. Tail_end_anim_zero_grp should go over curve_control_3_joint.
Parent the tail anim zero groups into the tail_grp.
Parent each control joint directly under its corresponding anim (not in the zero groups!)
To make the tail follow the root_anim, select the root_anim then the tail_grp and go to Constrain → Parent.
Lock and hide all the channels on each anim zero group.
We will now set up the anims to control the IK spline curve we created earlier.
Select the three control joints and then the tail_curve and go to Skin → Bind Skin. This will make the curve control
joints deform the curve, which will in turn deform the tail joint chain.
Test -- Try moving the control anims and see how the tail joints react.
More testing -- try rotating the tail_grp. Here we see a problem known as double rotation. The tail curve and the tail anims are both children of the tail group, so they
both see the rotation. The tail curve also sees the rotation through the binding of the tail control joints to the tail curve.
To fix this, we need to break one of these rotation paths. Go to the attributes of the tail_curve and turn off Inherits Transform.
Test -- Now when you rotate the tail_grp, everything should work as expected.
Now we need to reduce the clutter an animator has to deal with.
Lock and hide all the channels but the rotate ones on the tail_base_anim.
Lock and hide all the channels but the rotate and translate ones for tail_mid_anim and tail_end_anim.
Hide tail_curve, tail_ik_handle, and curve control joints.
Now for some clean up and organization.
Download circleArrow.ma and import it. Use File → Import (Options), uncheck Group and Use namespaces, and finally press Import.
Scale it until it covers the base of the mouse.
Freeze All Transformations on it (Translate, Rotate, and Scale) and name it mouse_top_con.
Group all the geometry and name the group mesh_grp.
Group all of the zero groups, head_anims and the tail_grp together and name it anim_grp.
Parent the mesh_grp, tail_grp, head_anims, root_joint, and root_anim_zero_grp under the mouse_top_con.
The mouse_top_con should now be the only top level object besides the cameras and default sets.
Test -- move the top con around. You may notice that when you scale the top_con, the mesh doesn't scale properly. There mesh is receiving a double transformation, so make sure
to go to the body_geo and uncheck Inherits Transforms.
Create display layes to organize the scene.
Create a new Display Layer called anims and add all of your anims except the top con to it.
Create another layer called mesh and add the mesh_grp to it.
Create another layer called joints and add root_joint to it.
Part 3: Creating eye blinks by using blend shapes
Before we bind the skeleton, we are going to create a few Blend Shapes. Blend Shapes are customized deformations that can capture subtle and
complex changes that would be difficult to control with joints. In this case we are going to use blend shapes to create a blink.
First we need to create a new shape to blend to.
Duplicate the body geometry and move it to the side. We will deform this copy of the geo and link it into the original geo
Now move the geometry (vertices) around to get the shape you want. We will start by making the left eye blink.
Let's connect this blend shape up to the original geometry.
Select the deformed geometry, then the original and go to Deform → Blend Shape (Options).
Call the BlendShape node eye_blinks.
You can animate the Blend Shape by going to Windows → Animation Editors → Blend Shape.
In the same window you can also rename your blend shape. It is likely that it'll be called 'body_geo1" or something similar. This name
is not intuitive. An animato would not know what this blend shape does. So, instead of leaving it like this, we will rename it to left_blink.
Now, make anoher duplicate of the body geometry and make the right eye blink. When you're done, don't create a new blend shape.
Instad, select the deformed geometry, then the original and go into Deform and down to the Edit section. Go to Blend Shape → Add (Options).
Instad, select the deformed geometry, then the original and go into Deform and down to the Edit section. Go to Blend Shape → Add (Options).
Check Specify Node and the eye_blinks node we made earlier should appear. Press Apply and Close.
Now in Windows → Animation Editors → Blend Shape there should be two blend shapes.
Rename your new blendshape right_blink.
If you want to modify your Blend Shapes later, rename the duplicated geometry to something meaningful and hide it.
If you like the deformation you can delete the geometry and the Blend Shape will remain.
NOTE: When turning in your assignment, delete the geometry that you duplicated for blendshapes.
Great! Now you have a mouse that can blink.
Part 4: Weight Painting
The last thing that we will do is make it so the mesh deforms as we move the anims around. We do this with the process called Weight Painting. Weight Painting is
the process of giving each joint a certain degree of control over parts of the character's mesh so that it deforms in a way that is both expeced and smooth. Weight Painting
requires the rigger to think about the range of motion that they and the animator want a character to have and making it possible for the animator to reach
the poses that they need.
Let's start by binding the mesh to the skeleton.
Select the body geometry and the following joint. We want to select only these joints because the other joints are considered end joints
and do not have controls. They are there to create the rest of the chain but they wouldn't have any control over the mesh. The reason we don't include the eye joints is
because they purely control the roation of the eyes, not their translation through space and so, they would not control the mesh.
Go to Skin → Bind Skin (Options).
Set the skin bind settings to the following:
Now when you move your joints, the geometry sould deform with them. You will notice however, that the deformation isn't very good.
Before we delve into the process of weight painting, let's look at how weight painting works. We will also look into the tool you will be using to weight paint, the Paint Skin Weights Tool.
When you open the tool for weight painting, you will see that it will turn the entire mesh black and there will be a band of white or grey. This band of white or grey is the area where a certain
joint has influence over the mesh. In the below picture, we see the area where spine_1_joint has influence.
Influence can be thought of as the amount of control that each joint has over different vertices on the mesh. Influence can range from 0 to 1. 0 means that a joint does not have influence over a vertex
at all and this is represented as black on the mesh. 1 means that the joint has full influence on a vertes and is represented as white on the mesh. Values in between 0 and 1 are represented as shades of
grey.
Multiple joints can also have influence over one vertex, but the added value of their influence must equal to 1.
If the gradient from black to white starts to get too ambiguous (such as when you add on a very small weight and you can't tell the difference between light grey and a slightly darker light grey), you can
change it to a color ramp by checking Use Color Ramp in the Gradient section of the Paint Skin Weights Tool. In this case, black is still no influence and white is still full influence,
but the in between colors range from blue to red. Blue has little influence and red has more influence.
You can select joints to paint influence for in the list hat shows up in the Influece tab. The mode you will be using is Paint and you'll mostly be using the Add operation.
Additionally, you'll be adjusting the Value to change the strength of your brush.
The best way to approach weight painting is to do it in a systematic manner. We will start by blocking out the weights for each joint and then blending between the joints to get a nice and smooth
deformation. The process is iterative so sometimes you will have to go back and fix weights if they aren't deforming in the way that you want.
So let's start by blocking out the weights for the spine. With your brush opacity set to 1, give each spine joint full influence over the mesh closest to it. For now, we want to give the head_joint
full control of that area. Later we will go through and split it up so that the other joints in the head have influence.
Next we are going to start posing our mouse. Let's start with spine_1. Grab the anim for spine_1 and key it (pressing down on s on the keyboard. This will make a red mark show up on the timeline at the bottom of the screen). Now move your
time slider to 10 and rotate the apine_1_anim to rotateZ = 15, then key it. Now go to 20 on the timeline and move the spine_1_anim to equal rotateZ = 20. Why do we do this? By setting small animations like this we can find problem areas in our weights.
As we can see, the spine_1 weights aren't all that great. There is a problem area in the back of the mouse where its collasping in on itself.
Let's try to fix this problem.
Turn the Value for your brush down to something really low, like 0.10. Now in the area with the bad deformations, try to smooth it out a bit and make it more gradual. You can switch between the root_joint and the spine_1_joint to try
and get a nice gradient. It's looking a little better, right? Focus all of your work on one side of the mouse. We can mirror them over later.
You will want to continue this process for all of the other joints in the body until you get something that you think deforms nicely. Key some poses as you go so that you know that the mouse will deform in a nice way when the animator uses it.
There is only one area where we are going to deviate from this technique. That area is the tail.
Grab the tail_mid_anim and move it up in the Translate Y direction. As we can see, the weights in the tail aren't terrible. They have the general movement that we want. So instead of getting rid of these default weights, let's use them to our advantage.
We'll work to smooth out these weights so that the transitions are nicer, like below.
Continue to test your weights are you finish painting certain parts of the body. When you are happy with the weights, it's time to mirror them over. Make sure that all of your anims are zeroed out. Then go to Skin → Mirror Skin Weights (Options).
You want to mirror over the YZ plane, Surface Association should be Closest point on surface. And Influence Association should be Closest Joint, then press Mirror.
The last step is to test the rig. Make sure everything works correctly and touch up any weight painting that needs work.