Need for the Tool
One of the challenges when building Wayward was that we needed a way to ensure that animations between the Girl and Robot were always in sync. In our case, from a gameplay perspective, the player controls the Girl while the Robot is controlled through AI. However, the girl can jump onto the back of the Robot, and once she is mounted the player then controls the Robot.
This is a typical “mount animation” problem and generally, there are two approaches you can take.
- The first option is to treat the characters as individual models, each with their own animations up until some point when the “mount” occurs. At that point, we then treat the characters as a single combined entity and the two are animated together in Maya. From the perspective of the game engine, the girl and robot share a single animated skeleton. All is good.
In order to create independent actions, the combined skeleton can then be masked (layered), for example to allow the girl to play a different animation clip while the robot continues to run.
- The second options is to keep the characters as individual models both when mounted and unmounted. Instead of combining them into a single unit, we create a seat joint on both models and drive the girl’s root position and orientation from the robot animation. (Similar to what you might do for a character holding a variety of weapons that share a common animation.)
The advantage of the first is that it guarantees smooth and synced animation when the Girl is mounted. The cost is that there would be a practically unavoidable “pop” when transitioning between mounted/unmounted states. Many games overcome this with a flash of particles or simply fade to black between mounting states.
We wanted to avoid the pop, but also maintain a smooth synced animation throughout. This is easy enough in theory, simply duplicate the animation state machine in Mechanim so that for every robot animation state there is an equivalent girl-mounted animation and keep the two sets in-sync at run-time. Easy, right! Well yes, as long no one EVER modifies the robot’s animation states, clip lengths, or blend times after they have been duplicated for the girl’s mounted animation state machine.
So obviously, there was just no way this would work as a manual process if we ever wanted to iterate on the robot animations.
My solution (which met the artists ultimate desires) was to create a tool in Unity that would allow any developer to quickly clone the animation states of the robot to the girl after any changes were made to the robot. From the animator’s perspective, this involved 5 button clicks for normal use (I could have made it just a single click, but I wanted to keep the tool generic enough to be reused in other situations.
- Delete hierarchy you’re about to replace (All states inside the Girls “Mounted_Robot” state machine)
- Select “Animation Controller – Clone…” tool from AtomJack menu
- Click “Make Assumptions”
- Click “Clone Animations” and make note of any errors.
- Click “Recreate Mount/Dismount Transitions”
Here are a few details about how the various fields and buttons in the tool.
Drop in the Robot and Girl Animation Controller Assets.
Name of Mounted State:
String name “Mounted_Robot” is used to find the target state machine name AND as a prefix for cloned states and state machines.
Girl Mounted Anim Prefix: This string is the prefix for animation clips. That is, the mounted girl animation associated with “Robot_loc_stand” is “Girl_mount_Robot_loc_stand”
Make Assumptions (Button)
This will preload the fields with expected values for project Wayward, specifically as noted above.
Clone Transitions (Button)
This will clone the animation controller hierarchy using the defined values. Note, if you haven’t deleted the old hierarchy, this will create doubled states and may not work as intended.
This clones all of the following:
- 1st level state machines
- 2nd level states (states of state machines)
- Blend trees
- State/State Machine transitions, conditions, and associated times
- All parameters in Robot Controller to Girl Controller
As implemented, this does not currently clone behaviors, default states, and “anystate” transitions since they were not needed for our purposes:.
There are two output windows. The first window lists any animation clips that the script could not find. The second shows a list of all successfully processed state machines, states, and transitions.
Recreate Mount / Dismount Transitions (Button):
After cloning states, you need to reconnect the mount/dismount transitions. Pressing this button will automate the creation of the following transitions and conditions:
Mount -> Mount_Robot_Stand
Has Exit Time = true;
Mount_Robot_Stand -> Dismount
Has Exit Time = false;
isMounting = false;
The final result was great. Not only did the mount and dismount transitions work great (as viewed below), but the models remained in sync through mounted combat, locomotion, and idle animations.
I hope to have some time in the coming weeks to upload either the source code or a complete Unity3D add-on. Stay tuned.