Merging animation files

Our skinned animation sample supports any number of animations, which are imported from the input BoneContent.Animations by the SkinnedModelProcessor, stored in the output SkinningData.AnimationClips dictionary, and can be switched or blended between in whatever way your runtime game code sees fit.

But if you try to create a model which contains multiple animations, you will discover that current Autodesk FBX exporters only support a single animation take per FBX file!

One solution is to concatenate all your animations into a single long one, then choose the appropriate time region when you play back the data. For instance, "run" might be located between 2 sec and 3.1 sec, while 3.1 sec to 5.4 sec is "jump". Kinda like the animation version of sprite sheets, this works ok, but it can be a pain keeping track of which data means what.

Another approach is to export each animation into a separate FBX file, then use a custom processor to merge them.

  • Add the following processor code to a Content Pipeline Extension project
  • Insert whatever other processor code you need (eg. the SkinnedModelProcessor from our skinning sample) at the TODO comment
  • Build the Content Pipeline Extension project
  • Add the Content Pipeline Extension project to Content \ References
  • Export each animation into a separate FBX file
  • Add just one of these FBX files (the master version, which will provide the model geometry) to your Content project
  • In the Visual Studio properties for this master FBX file, set the processor to MergeAnimationsProcessor
  • Click the plus icon to the left of the processor selection, which will expand the processor properties
  • In the MergeAnimations box, type semicolon separated names of the other animation files, eg. "run.fbx;jump.fbx;turn.fbx"
  • Build your content, and look in the output pane to confirm that it loaded and merged the expected animation data
  • Now your BoneContent.Animations can contain as many different animation clips as you like!


using System.Linq;
using Microsoft.Xna.Framework.Content.Pipeline;
using Microsoft.Xna.Framework.Content.Pipeline.Graphics;
using Microsoft.Xna.Framework.Content.Pipeline.Processors;

namespace MergeAnimationsPipeline
    public class MergeAnimationsProcessor : ModelProcessor
        public string MergeAnimations { get; set; }

        public override ModelContent Process(NodeContent input, ContentProcessorContext context)
            if (!string.IsNullOrEmpty(MergeAnimations))
                foreach (string mergeFile in MergeAnimations.Split(';')
                                                            .Select(s => s.Trim())
                                                            .Where(s => !string.IsNullOrEmpty(s)))
                    MergeAnimation(input, context, mergeFile);

            // TODO: whatever other processing you need.
            // eg. if you use SkinnedModelProcessor from our sample, that code would go here.

            return base.Process(input, context);

        void MergeAnimation(NodeContent input, ContentProcessorContext context, string mergeFile)
            NodeContent mergeModel = context.BuildAndLoadAsset<NodeContent, NodeContent>(
                                                new ExternalReference<NodeContent>(mergeFile), null);

            BoneContent rootBone = MeshHelper.FindSkeleton(input);

            if (rootBone == null)
                context.Logger.LogWarning(null, input.Identity, "Source model has no root bone.");

            BoneContent mergeRoot = MeshHelper.FindSkeleton(mergeModel);

            if (mergeRoot == null)
                context.Logger.LogWarning(null, input.Identity, "Merge model '{0}' has no root bone.", mergeFile);

            foreach (string animationName in mergeRoot.Animations.Keys)
                if (rootBone.Animations.ContainsKey(animationName))
                    context.Logger.LogWarning(null, input.Identity,
                        "Cannot merge animation '{0}' from '{1}', because this animation already exists.",
                        animationName, mergeFile);

                context.Logger.LogImportantMessage("Merging animation '{0}' from '{1}'.", animationName, mergeFile);

                rootBone.Animations.Add(animationName, mergeRoot.Animations[animationName]);

Comments (28)

  1. David Black says:

    Or you could use blender, which exports multiple "Actions" just fine.

    The only caveat is that you need to hack the fbx exporter to generate transforms compatible with xna.(just do a google search).

  2. mayaterror says:

    The "export separate .fbx files, then merge" approach is an artist's worst nightmare.  I'm pretty shocked that you are advocating this, Mr. Hargreaves.  Furthermore, my comparisions between .fbx and .x have shown that typically .fbx files are nearly an order of magnitude larger in file size than a .x.

    The lack of definable clips and the file size were why on  we opted not to use .fbx on my XNA project, instead we went with .X using KW-Xport, which supports the ability to name the individual clips within a single file.

    The programmer on my project was able to throw together a utility to parse the .x file and add in the clip names based on a .txt I wrote that explicitly defined the frame ranges for each clip.  So now we don't even have to fool with inputting the clips into KW-X!  Again bypassing the .fbx/merge approach.

    The only problem we're having now with animation in XNA is this stupid "1-second bug," where clips of less than a second in length get some dead space added to them.  We've managed to solve this by stretching the clip to be longer than a second and then scaling the clip back to the correct size in code.  What framework designer didn't realize that most game animations are under a second? – I thought this was pretty ridiculous.

  3. ShawnHargreaves says:

    > The "export separate .fbx files, then merge" approach is an artist's worst nightmare. I'm pretty shocked that you are advocating this, Mr. Hargreaves.

    I think that's a little unfair 🙂

    I'm glad you have found an exporter and workflow that meet your needs. That's great. But many people like FBX, and prefer working with separate files vs. time offsets. Which is also great: people should be free to do whatever makes them the most happy!

    I was just sharing some code that might be helpful for those people who happen to prefer the latter approach. I fail to see what is so shocking about that?

  4. mayaterror says:

    I've just come to respect your ideas and opinions on the technical aspects of game design, and your perspective from working in the industry – and that .fbx technique just seems like a hack that someone of your calibur would not use…

    But I guess if it works, and people like it – to each his own.

  5. Chris says:

    More MotoGP rendering techniques please 🙂

  6. Eclectus says:


    > .fbx technique just seems like a hack that someone of your calibur would not use…

    I don't think its a hack. As Shawn mentions, it is conceptually similar to sprite sheets. I've worked with animators who like things all in one source file, and ones who like them to be separate files, because the latter solution allows the names of the animations to be easily viewable, you can see the sizes, time when they were last modified etc.

    The concept of merging many things into one is controversial, I'd agree, but not a hack, it is a a pipeline decision. You can apply it with audio samples too. Fewer files mean less seek time, so its good for loading speed. This makes it feel like a valid option, and I think it helps to have options?

  7. Ronzan says:

    This is excellent Shawn!

    I've been using all kinds of other methods for some time to achieve exactly this goal.

    I want to have the animations in different files, the artists wants that too!

    You can reuse animations on different models and you can easily find a specific animation. Also no hacks or overhead in maintaining text/xml files with animation config stuff.

    Nice, thanks!

  8. Luke says:

    I *knew* I'd be seeing this as a blog post Shawn! 😉

  9. mayaterror says:

    The *only* reason I used the word "hack" was because, as Shawn himself admits, the .fbx exporters only support a single clip per file, making .fbx "broken" in my opinion.  You're therefore having to put together some code to make it work, i.e. a hack.  I guess you could argue against that, but it's really inconvenient, you gotta admit.  Anyway I'm not trying to argue or be controversial, I agree it's good to have this kind of info availiable because for a long time on our project we've debated the merits of the "master animation file" vs. "single clip" approach, and the debate still seems to come up all the time.

    I think it's like some kind of weird twist of fate that Shawn always seems to be posting about whatever we're working on in XNA at the moment…

  10. Man without a Name says:

    I want to try this out.

    We have had some problems with laying out all the animations in one .fbx file, then splitting them up during import using the XNA Animation Component library. The animation clips seem to bleed into each other when we do that. It is like the boundary frames for each clip that we supply to the processor are not respected. This error is both confusing and very annoying.

    Also, having a simple clip in each file seems to be the more natural way of working for my artist.

    If this method separates the clips cleanly, I will be happy.

  11. Man without a Name says:

    I am a bit worried about the space this is going to take.

    The .fbx files are quite large, up to 10 MB, and multiplying them by number of animation clips will quickly use a lot of room on the source repository and make the project a bit unwieldy…

  12. David Black says:

    >>>I am a bit worried about the space this is going to take.

    The .fbx files are quite large, up to 10 MB, and multiplying them by number of animation clips will quickly use a lot of room on the source repository and make the project a bit unwieldy…


    This seems like a valid concern to me. My main player + perhaps 10% of the final animations and less than full detail is about 5MB just for the mesh + anims. But even worse is that the intermediate file for this is 22Mb, I dread to think what it will be eventually. Luckily I dont need multiple files due to the fact I am using blender:-)

    Is there a way to try turning off intermediate file generation for selected fbx models? I seem to remember an attribute, but that was presumably just if you write the importer…


  13. Aaron Schultz says:

    My team and I had to deal with this crap when we were working on an independent study project in the spring. At the time, the programmer we had working on animation ended up having to go into Maya, do all those exports as ASCII FBXs, and then copy-paste the takes from each one together. Horribly inefficient, but we were lucky in only dealing with a few models. This probably would've been a little easier, and has the benefit of not requiring the FBX files in bloated ASCII format. Really, though, Autodesk just needs to fix their damn exporter.

  14. mike says:

    The fbx exporter I use does export takes just fine from Blender, and I've been able to import several takes from one FBX file into XNA using the example skinning processor. I got this problem only today when converting my XNA 3.1 project to XNA 4.0. It seems the problem is in MeshHelper or perhaps even before the NodeContent reaches the processor. It would be nice if I didn't have to recreate my whole workflow and start splitting stuff in different files just because of this, as it worked fine in 3.1.



  15. Rich says:

    I also have been using Blender as the modeling tool and export multiple clips. I have not upgraded to 4.0 yet. I currently use a custom processor to pre-build all content to xnb files, so that the game loads quickly. Will xnb files built with 3.1 load in 4.0?

  16. alecto says:

    i agree with you maya.  ESPECIALLY since in every other version you could have multiple animations per fbx file.  Did they go out of their way to make it not work like that ?  Now im trying to figure out what Im gonig to do

  17. alecto says:

    I only just now fully comprehended the post.  My questions are a) do u know a way to only export animation info from 3d studio max and b) failing that does this method read motion builder animation only files?  My model is nearly 8 mb and having to include it 5 times for 5 dif animations is very heavy

  18. cjhazard says:

    The FBX SDK clearly states…

    "The Animation stack is a collection of animation layers. The Fbx document can have one or more animation stacks. Each stack can be viewed as one "take" in the previous versions of the FBX SDK.  The "stack" terminology comes from the fact that the object contains 1 to n animation layers that  are evaluated according to their blending modes to produce a resulting animation for a given attribute."

    So the FBX SDK DOES support multiple takes per file.  So WHY does the XNA FBX importer not?

  19. Aranda says:

    @cjhazard – see Shawn's response here:…/426449.aspx

    It seems fair enough that they didn't have time to support the new "stack" format, however I'm not sure I agree with this statement "the multiple takes feature had never been well supported or widely used, we suspected that few of our customers were actually using it". Judging by the comments on this post there were a reasonable number of people using the feature via the (albeit modified) Blender FBX exporter.

  20. kerry says:

    Works, great. If anyone needs the code let me know…got it all merged together in a nice file.  So you basically export out 1 master .fbx file in ascii or binary as fbx 2009, with the mesh and skeleton. Then export out a bunch of different animations without the mesh, as ascii files and rename the takes to whatever you want…but probably should match the name.fbx file.  Very nice, and the resulting .fbx file is rather small…

  21. Nick says:

    "One solution is to concatenate all your animations into a single long one, then choose the appropriate time region when you play back the data. For instance, "run" might be located between 2 sec and 3.1 sec, while 3.1 sec to 5.4 sec is "jump". Kinda like the animation version of sprite sheets, this works ok, but it can be a pain keeping track of which data means what."

    I would like to try this but dont see where one can choose the appropriate time region withing the animation player.  Am I missing it or do I need to add something to do this?

  22. Ben Ritter says:

    Alright, misread this first time through, it's actually much more useful than I originally thought. Thanks for posting Shawn.

  23. Charles says:

    If you just include the bone names in the animation file, you can treat each FBX file as a different content item instead of this merging method. I just delete all or most of the geometry from the file and leave only the animation, then import it.

    That said, the transforms in the bones for a load FBX file in XNA are the first frame of the animation. If the transforms in keyframes for a bone are that same as the transform in the bone, they are filtered out somewhere along the line, so there is no animation for that bone at all. This means bones that do not move in an animation don't include any keyframes, even if they are different from the bind pose. The solution is to create a keyframe at time zero if one does not already exist. My skinned model demo at does this.

  24. That Kid says:

    You're my new hero 😀

  25. JaekSmith says:

    So…  After having hand split and FBX file to test the MergeAnimationsProcessor, I crap-hacked a processor that did the file split just before the merge just to see if it would work – and it did.  (Where works is defined as worked with single test file I exported from Blender).

    (I couldn't find the filename – probably too far in the pipeline, which I haven't studied yet).

    SplitAndMergeAnimationsPipeline (as mentioned) is a pre-alpha prototype will-burn-your-eyes everything-intentionally-done-wrong crap-hack, but just incase anyone is wishes such pain:…/SplitAndMergeAnimationsProcessor.cs

    WARNING: Use at your own risk.  (I suggest you at least look at the code and touch anything you don't feel safe about – such as directory deletions).

    To use:

    – Set Content Processor to SplitAndMergeAnimationsPipeline on the FBX file.

    – Under the SplitAndMergeAnimationsPipeline, re-specify the filename in the OriginalFilePath property of the processor. 😛

    – Tremble in fear as the universe cracks open from running concept-code.

    (And, yes, there may just be some dark hilarity in this situation…) ;^)

  26. JaekSmith says:

    Note: I crap-hacked Shawn's MergeAnimationsProcessor into SplitAndMergeAnimationsPipeline.  The merging (the real worth) is still all Shawn's work.  I just crapped in it. 😉

  27. riash says:

    i have a problem with naming the animation clip in code. just replace the animation clip name "Take 001" that comes with with model by my animation clip name which was separate FBX file. when i compile the code i got the "KeyNotFound Exception was unhandled". how to handle the error to get ridoff

  28. Abir says:

    Hello I want to import a model (animal) in 3D xna wp7 4 (7.1)

    And I want to manually rotate in 3 dimensions.