How to Rapidly Set Up Controls in Maya

Step by step guide on optimizing your Maya rigging workflow with MEL

7 min. read

Brief Introduction

Don’t you hate going through the Outliner and manually creating, orienting, renaming, and constraining every Transform? I had to do something after several attempts to find anything on the internet that is helpful. Setting up Controls manually is very repetitive, and hopefully you will never have to do that again.

I want this guide to be useful for Gamedevs and Riggers alike - and since Maya LT does not support Python, we’re going to use MEL for this guide. Feel free to use my code and make it your own.

Rosa's Character Rig - Overview

… I wish someone shared these scripts 4 years ago.

1. Set up your Rig’s joints.

Just create a bunch of joints like you would typically do when rigging. Make sure you have a consistent naming convention. What we’ll do later is replace _jt and _end (the end joints), with _grp and _end_grp. We’ll use some MEL to generate a group of Transforms that will later allow us to manipulate its orients for our controllers.

You’d normally want all the joints under a root for your rig, but that’s up to you. Take a look below to see how I’ve set it up!

2. Select the Root Joint and run the following script.

As you can see below, I have selected the Root Joint of the Character. Open up the script editor via Windows > General Editors > Script Editor from the Navbar.

Rosa's Character Rig - Groups

Now we’re going to run a script. Simply CTRL+c the script below and CTRL+v it into the MEL tab inside the Script Editor. You will want to adjust the substitutions in the $name variable to match your naming convention. Make sure you don’t have two joints with the same name.

The script will create a group of transforms while preserving the joints’ orientations.

Rosa's Character Rig - Groups

Joint to Group Orientation Script

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// This procedure will iterate through whatever joint is
// passed through the parameter and create a transformation group
proc string iterateGroup(string $jt){
if (!`objExists $jt`) return "";
$name = `substitute "_jt" $jt "_grp"`;
$name = `substitute "_end" $name "_end_grp"`;
$grp = `group -empty -parent $jt -name $name`;
$jts = `listRelatives -type "joint" $jt`;
for ($i = 0; $i < size($jts); $i++){
if (!`objExists $jts[$i]`) continue;
$next = iterateGroup($jts[$i]);
if (!`objExists $next`) continue;
parent $next $grp;
}
return $grp;
}
// The main procedure will generate a hierarchy of groups that preserves the
// original orientation of whatever joint structure is selected
proc main(){
$init = `ls -sl`;
for ($i = 0; $i < size($init); $i++){
$grp = iterateGroup($init[$i]);
if (!`objExists $grp`) continue;
parent -world $grp;
}
}
main();

3. Set up and Constrain your NurbsCurve Controllers.

The next step would be to manually create nurbsCurves and use them as controllers. We’ll be parent-constraining the controllers to eachother automatically, but also we’ll constrain the controllers to the joints manually. Make sure you set the rotations and translations of the controllers to 0, and freeze their scale transformation.

Due to every rig being different, it will unfortunately be un-realistic to write a script that constrain the controllers to the joints directly. However, we can at least automate the first half of this step - which is to constrain the controls together. Simply select the root of your rig and run the script. Make sure you delete unwanted constraints for the IK’s.

Please save your file before running this script. Don’t trust yourself nor the script!

Parent Constraint Script (For Curves)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
// This procedure will parent-constraint controls to every child of the control's
// parent besides itself (I hope that makes sense lol)
proc string iterateGroup(string $tr){
if (!`objExists $tr`) return "";
$c = `listRelatives -type "transform" $tr`;
string $f = "";
for ($i=0; $i<size($c); $i++){
if (size(`listRelatives -type "parentConstraint" $c[$i]`) > 0) return $tr;
if (size(`listRelatives -type "nurbsCurve" $c[$i]`) > 0){
$f = $c[$i];
break;
}
}
if (!`objExists $f`) return $tr;
for ($i=0; $i<size($c); $i++){
if ($f == $c[$i]) continue;
$a = iterateGroup($c[$i]);
if (!`objExists $a`) continue;
parentConstraint -mo $f $a;
$debug = "Constrain: " + $f + " to " + $a;
print {$debug};
}
return $tr;
}
// This will initialize everything
proc main(){
$init = `ls -sl -dag`;
for ($i=0; $i<size($init); $i++){
$a = iterateGroup($init[$i]);
}
}
main();

Result

Rosa's Character Rig - Controls

4. Bonus! Automatically rename your Controllers.

This script will allow you to automatically rename your NurbsCurve Controllers so that you don’t have to name everything! Just select the Root of your Rig’s Controls and it will automatically rename everything below it. The script replaces the _grp suffix with _ctrl, but you can easily change it to match your preferred naming convention.

Rosa's Character Rig - Controls

Curve Rename Script

1
2
3
4
5
6
7
8
9
10
// This will rename every nurbsCurve's transform under the root you selected.
$all = `ls -sl -dag`;
for ($i=0; $i<size($all); $i++){
if (!`objExists $all[$i]`) continue;
if (size(`listRelatives -type "nurbsCurve" $all[$i]`) == 0) continue;
string $p[] = `listRelatives -p $all[$i]`;
string $a = $p[0];
string $n = `substitute "_grp" $a "_ctrl"`;
rename $all[$i] $n;
};