Root Motion Computer for Unity

I recently finished up a new component for Unity as part of a contract job with Mixamo. For those of you who are unaware, Mixamo provides an online motion capture download and retargeting service powered by HumanIK. It lets you use sliders to creatively adjust a piece of motion capture data and then automatically retarget it onto your own hierarchy and download it for use in your game. It’s really slick and pretty affordable, so it’s definitely worth checking out, particularly for any indie developers out there.

At any rate, the component that I created is designed to let animation data, rather than procedural velocity values, drive a character’s motion in space. The component sits on top of Unity’s animation API to let you simply play, crossfade, and blend animations using any of the existing API methods, and the computer takes care of everything else after the fact. The way it works is by tracking the position and rotation of the pelvis in the space of the character’s root node for each active AnimationState and then backward applying this motion to the root node itself and snapping the pelvis back into its position hovering over the root. Since the source code is all available in the project, I won’t belabor the details too much here, but you can certainly ask me if you have any questions. (The one thing perhaps worth mentioning, as an addendum to the video, is that the pelvis forward axis is not strictly necessary for computing output: only for displaying debug information. For computation, the character’s rotation is determined using the pelvis right axis.)

You can download an example project from Mixamo that contains the component as well as a sample character with some animations. Because the tutorial video on the Mixamo website is compressed pretty substantially, I have also uploaded a copy to my Vimeo account in case you would like to watch it in full HD resolution.

26 thoughts on “Root Motion Computer for Unity”

  1. Wow Adam, this is a very impressive bit of code you have here. I had dabbled with Mixamo before, knowing you’re helping them put out awesome tools pretty much seals the deal on where I’ll get animations when I need them. Rock on man.

  2. Good to hear from you, David! I’ve been quite happy with the animations I’ve gotten from Mixamo so far; it’s really helped speed things up. Hope everything is going well for you and your family!

  3. Hello.

    I would love to have a way to contact you about this. I have 3 animations blended on top of each other (layers 0-2), where layer 0 is all the translation needed to calculate the pelvis movement.

    Layers 1 and 2, run mixingTransforms…above the pelvis. Basically, I have a character which walks and idles on layer 0, layer 1 blends vertical rotation…and layer 2 does a reload animation.

    The script really doesn’t handle this case. It seems that it can’t handle mixingTransforms…cause it just is looking at blend weights.

    I know this is the issue cause when I comment out layer 1 and 2, the rootmotioncomputer works, and putting them back in, breaks everything…

    stringa

  4. Ohh sorry, it was my fault, With a biped imported from Max the Pelvis is Bip001 and the root node are the top most object of the hierarchy, and the pelvis right axis is (0, 0, -1). Hope this tip help for 3ds max biped users

  5. I’m sorry for my poor English.
    I attached ”Root Motion Computer” to my bone animationed character .and worked verry well!
    This is very good source.
    But when I changed the Scale of the character ,the moving distance of root bone is original length.
    Other bones are working as a changed scale.

    I think I remake the charactor in the 3D modeler ,it will work good.
    But I want to change the scale of my character dinamicaly by Scripts.

    If you know the solution of this problem,Please tell me.

    best regard.

  6. Hi,

    Depending where exactly the RMC object falls in your hierarchy and what you need it to do, you can do something like this before the call to rootNode.Translate()

    dPosition.x *= rootNode.localScale.x;
    dPosition.y *= rootNode.localScale.y;
    dPosition.z *= rootNode.localScale.z;

    You can optionally use lossyScale if it makes sense for what you need to happen.

  7. Hi Adam, fabulous contribution to Mixamo and community at large. I’m still getting my hands wet with character animation to add to my indie game. Does the RMC only work for Mixamo characters and animations? I plan to use those, but I also tried to apply RMC to the free Spartan King character w/animations from the Unity Asset Store. I hace him animating fine, but RMC does not apply motion to his CharacterController. The vector displacement ends up being zero no matter which animation is running. Hoping you might have some helpful suggestions. Thanks.

  8. Hi Ted. The RMC works with any character, not just Mixamo characters. It basically requires that you set it up properly, and that the character was animated with root motion applied to it. I’m not familiar with the Spartan King character, but it sounds like maybe he has in-place animations, rather than animations where he actually moves forward.

  9. Hi,

    You did a great piece of software.
    I have a question: are the animations needed to be move forward ? Because I have a bunch of in place animations which seems do not work. The GO is not moved (exported in this way from 3ds Max).

    So my question is: what kind of animations are required? Moving forward or in place ?

    Thank you !!!

  10. Hi, Thanks for providing this script! It’s something that was sorely missing from Unity.

    I did get it to work perfectly on one 3ds max character/animation I downloaded from the web. I’m having trouble making it work with a character I made myself in 3ds max.

    I made a mesh, added a biped, used the skin modifier on the mesh to rig it to the biped, and loaded a motion captured animation. I bring this character/animation into Unity, and add the RootMotionComputer script, with my custom (simple) controller script (basically crossfades between an idle and a walk animation, same script that worked fine with the downloaded character). My character moves, and it seems that the RMC is moving the position of the GameObject along with the animation, judging by the GameObject gizmo and my own custom debug drawing code. If I stop moving the character before the end of the walk animation cycle, everything seems perfect.

    HOWEVER, if I keep playing the animation and it gets to the end of it’s loop, the GameObject (and model/etc) snaps back to the starting point.

    If I set the import on the animation to “Default/Once”, it does NOT snap the GameObject back to it’s starting point, and I can move around the scene as expected, HOWEVER, the animation eases in and out at each loop, so that he gets a sort of stuttering/speedup/slowdown motion as it gets to the loop point.

    Is there some extra setup I need to do in 3ds max or the Unity importer to make this looping animation not snap back to it’s original location when it reaches it’s loop point?

    Thanks!

  11. Hi Ed,

    I’m not aware of any such problems, but you’re welcome to email me an FBX file and I can take a look at it sometime.

  12. Hi,
    I have it working for an anim when wrapmode is loop but for other anims I need it to work for wrapmode once but it always glitches at the point where the anim ends? Is there a fix for this? Thanks.

  13. Hi there,

    I haven’t heard of this problem specifically, but, as I mentioned to Ed when working with him, Mixamo took over support of this tool awhile ago, and I’m not sure what all changes may have occurred. That said, it seems perhaps at least some changes in Unity itself were to blame in his case, and it may be related for you, too. If you look in the code, there is a section where I record wrap information on a clip and I did some things to deal with a problem whereby Unity would reorder the AnimationStates in the animation component during iteration. Possibly try creating a List<AnimationState> before the iteration and iterating it instead of the Animation component itself. If you’re having further trouble though, I’d really suggest contacting someone at Mixamo, as they’d probably be better suited to support the tool at this point.

  14. Hi,

    I solved the same bug as jks mentioned.

    In the function, named SetupNewAnimInfo(AnimationState aState) that calc pelvis position at normalTime =0 & 1 with anim.Sample(), You have to add anim.Stop() between both Sample() to solve problem.

    In my case, the bug happen only with tool named Sage. (Sometimes glitches happened with object using Sage, sometimes object without Sage, but both of two object has RootMotionComputer.)

  15. Sorry, the previous metion that I wrote is not a solution for both of Once and Loop wrapmode. I’m trying to fix bugs.

  16. Hi Idid try to download this component but it is no longer avaible. I am new in game developping I have lot of animations with “in place motion” I realy do not know hot to add root motion to these animations. I do not know if you can suggest me some script or procedure to “turn lef”, “turn right” and so on with animations that do not have root motion. Thank you
    Paola

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.