Maya to Unity Animation Pipeline
This is a high-level overview of how our Maya-to-Unity animation pipeline works for Rogue Islands.
Unity already has a tight integration with Maya, but there are still many different ways to approach the problem of generating skeletal animation for Unity.
- 1-click exporting from Maya
- 1-file per animation, no specifying frame-ranges
- fast, easy-to-animate, character rigs
- easy to modify rigs, and automatic-updates to animations
- 100% procedural rigging (no time for manual rigging)
- Simplicity. We can’t afford to spend time debugging complex things.
This is how I get animations from Maya into Unity:
Notice the complete lack of branching. This is nice linear pipeline.
1.a. Modular Procedural Rigging
The pipeline starts with our Python-based procedural rigging system. I will cover this system in subsequent blog posts, but suffice to say its comprised of a set of python modules which roughly correspond to various body parts.
We have modules for legs, arms, heads and arbitrary FK-chains.
Each module sub-classes a base ‘RigModule’ class which supplies functions for building the rig and then connecting it to other modules via publicly advertised ‘hooks’ and ‘handles’.
A typical animation rig might be comprised of 5-10 modules which control different joints in the skeleton file.
1.b. Skinned Mesh (.ma)
This is the final character which plays animations in Unity. Unlike the raw animation/rigging files, this one lives in the Unity asset folder and is built by Unity.
It is a very simple Maya scene that contains only 3 elements:
- Mesh: A single combined character mesh (1 mesh = 1 draw call)
- Skeleton: A plain FK skeleton, with a consistent structure starting with a root joint at the origin (which is used to move the character from code).
- Skinning Data: a skinCluster deformer with tuned weights
2. Rig Definition (.py)
This is a custom python module specific to each character. It’s job is to apply rig modules to a skeleton file to generate a control rig which an animator can use.
The rig definition does the following:
- Adds modules for each body part: self.addModule(leg)
- Defines what joints belong to each module: leg.joints = [joints]
- Specifies how each module connects to other modules: self.connect(leg,hips)
- Specifies a skeleton file to operate on: self.skeleton = “c:/dragon.ma”
The base RigDefinition class has a build function which runs the build functions for all of the modules and then connects all the hooks and handles to parent the control rig correctly.
For example, the Neck-hook attaches to Spine-handle and the Leg-hook attaches to Hips-handle etc…
The build function then saves the resulting animation rig file to disk (#3).
3. Animation Rig (.ma)
When the rig definition is built (ie by running, dragon.build() ) the output is a Maya file that is ready to animate. It includes:
- A copy of the Skeleton file (with intact FK skeleton, constrained to the control rig)
- Controller curves for easy manipulation of the puppet
- Advanced control methods (IK, auto-twisting/stretching, look-at, IK/FK blending etc)
4. Animation Scene (.ma)
The Anim Rig from step 3 is referenced into a new animation scene for each animation clip (ie, dragon_run.ma, dragon_bite.ma etc). Using Maya’s file referencing feature is a huge time savings. By referencing the rig, we can propagate model and rig changes through the whole pipeline automatically.
When the model/rig needs modified, we go back to the Skeleton file and make the change there. Then re-run the “dragon.build()” procedure to auto-generate new “DragonRig.ma” files.
Now when we open our animation scenes, they automatically have the latest dragon rig.
5. Exported Animation (.ma)
We have a 1-click Python routine which is run on an animation scene. The output is an animation maya file which is consumed by Unity and turned into an animation clip. One animation scene file per clip.
The export routine simply bakes all animation from the control rig into the FK skeleton. It then saves only the skeleton with the FK animation data to a separate Maya file which is stored in the appropriate Unity asset folder.
Note on FBX: we use Maya ASCII format instead of FBX. While this may incur an additional build-time cost, I find it simplifies the export pipeline greatly by just letting Unity deal with the conversion internally (Unity uses the FBX SDK to import Maya files and automatically selects the correct FBX conversion settings for you).
We have a batch export tool which can be used to auto-update animations when a model/skeleton is changed. Doing a full batch export will rebuild the animation rig, open all of the animation files (using the newly generated rig) and re-runs the export routine on each one.
All of this is then abstracted into a single click which propagates any model/rig change from the Skeleton file, to the animation rig, to all the animation scenes and finally into Unity where the updated clips are automatically reimported (by Unity).
This is an important point: we can make a change to an animation rig and with a single click propagate that change to every animation in the game.
All of this is facilitated by a simple folder structure where each animation rig lives next to all of it’s animation scenes. We assume, by convention, that any Maya file in this folder is an animation. This is outside of the Unity asset folder.
Note on Unity’s Asset Folder: Only the exported Maya animation files live in the Unity asset folder. This is to keep a clear separation between final baked-out game content and the raw assets used to author it. It also prevents Unity from building redundant maya files as Unity will automatically build any and all .ma/.mb files stored within the project’s asset directory. Therefore, we only put Maya files in the Unity asset folder if they are intended to be used by Mecanim.
This animation pipeline has been production proven.
It meets all of the requirements outlined at the start of this post and it’s proven to be very easy to use and modify. Python sits at a good level of abstraction for automating common rigging and animation work.
The three main features we rely on are:
- a modular procedural rigging system
- Autodesk Maya’s scene referencing system (to propogate rig changes)
- a simple batch exporter
When used together, these systems allow for rapidly produced, high-quality animations with the flexibility to make changes to the model and/or rig at any time. Completely rebuilding a rig is a 1-click process that finishes in a few seconds.
Ultimately, we needed to concentrate on the actual animation and this pipeline allows us to do that. I’ve pasted a sample animation below. It’s a run cycle for Motwort, the main character in Rogue Islands.