Search Unity

  1. Are you interested in providing feedback directly to Unity teams? Sign up to become a member of Unity Pulse, our new product feedback and research community.
    Dismiss Notice

Turning off Animation Compression doesn't use keys in FBX

Discussion in 'Animation' started by Brad-Newman, Mar 27, 2020.

  1. Brad-Newman

    Brad-Newman

    Joined:
    Feb 7, 2013
    Posts:
    156
    I'm doing the following:
    1. In Maya I compress my animations by simplifying the curves.
    2. Export FBX to Unity
    3. Turn Animation Compression to OFF
    4. Compare the keyframes in Maya and Unity and see that Unity has baked dense keyframes into the curves, basically overwriting my compression done in Maya. More keys are baked for rotation and scale, and fewer are baked for position.
    Expected Result:
    1. In Maya I compress my animations by simplifying the curves.
    2. Export FBX to Unity
    3. Turn Animation Compression to OFF
    4. Compare the keyframes in Maya and Unity and see that the keyframes are identical.

    I've opened the FBX in Maya and can see that the keyframes in the FBX are indeed compressed, so nothing is going wrong on export.

    What happens exactly when you turn off compression in Unity? Is there anyway to make Unity use the exact keyframes in the FBX?
     
  2. Brad-Newman

    Brad-Newman

    Joined:
    Feb 7, 2013
    Posts:
    156
    Here is a comparison between an X Rotation curve in the FBX opened in Maya vs the same FBX in Unity. The animation in Unity has Animation Compression set to OFF. Why are the curves different and don't line up when overlaid like this?



     
    Last edited: Mar 27, 2020
  3. Kybernetik

    Kybernetik

    Joined:
    Jan 3, 2013
    Posts:
    1,765
    Try opening the FBX in a text editor and counting the number of keys to determine whether it's caused by the export or import. Not sure what you could actually do with that info, but it would help narrow down the issue.
     
  4. Brad-Newman

    Brad-Newman

    Joined:
    Feb 7, 2013
    Posts:
    156
    When I open the FBX in Maya there are 34 keyframes for the curve shown in the images above.
    When I open that same FBX in a text editor, there are 34 keyframes listed.

    It appears Unity is baking the curves on import when Anim. Compression is OFF. I want to disable this baking and read the exact 34 keyframes that are in the FBX file.

    Here are my import settings:

     
  5. Kybernetik

    Kybernetik

    Joined:
    Jan 3, 2013
    Posts:
    1,765
    I've never used Resample Curves, but this sounds exactly like what I would expect it to do if it was enabled so you could try enabling then disabling it again. Either way, you should report a bug via the Help menu because something's not right here.
     
  6. Brad-Newman

    Brad-Newman

    Joined:
    Feb 7, 2013
    Posts:
    156
    While looking at the OnPreprocessAnimation and ModelImporter classes, I came across a clue when writing this code:

    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEditor;
    3.  
    4. public class AnimProcessor : AssetPostprocessor
    5. {
    6.     void OnPreprocessAnimation()
    7.     {
    8.         ModelImporter modelImporter = assetImporter as ModelImporter;
    9.         modelImporter.resampleCurves = false;
    10.     }
    11. }
    modelImporter.resampleCurves shows this message in a pop-up in Visual Studio:

    "If set to false, the importer will not resample curves when possible. Read more about. Notes: -Some unsupported FBX features (such as PreRotation or PostRotation on transforms) will override this setting. In these situations, animation curves will still be resampled even if the setting is disabled. For best results, avoid using PreRotation, PostRotation and GetRotationPivot. - This option was introduced in Version 5.3. Prior to this version, Unity's import behaviour was as if this option was always enabled. Therefore enabling the option gives the same behaviour as pre-5.3 animation import."

    So my best guess is that the FBX uses PreRotation / PostRotation, and therefore setting resampleCurves = false has no effect, and the curve is resampled on import. Does anyone know how to avoid using PreRotation and PostRotation?

    We are using a Generic rig, instead of a Humanoid rig, and as a result when compressing in Unity this can lead to the feet sliding around. My overall goal here is to avoid sliding feet by applying more compression to the upper body joints and less compression to the legs and feet. Since Unity's animation compression applies to the entire skeleton, I was trying to do the compression in Maya to apply different amounts of compression to different joints.

    If I can't avoid using PreRototation/PostRotation, are there any methods out there to do different amounts of compression for different joints inside Unity? Maybe a plugin in the Asset Store?
     
  7. Brad-Newman

    Brad-Newman

    Joined:
    Feb 7, 2013
    Posts:
    156
    Haven't found a way to disable Pre / Post Rotation, so I hacked the ASCII FBX by deleting any lines mentioning Pre or Post Rotation, such as:

    P: "PreRotation", "Vector3D", "Vector", "",2.65108551249784,27.6016975163226,2.69184586855337

    These PreRotation values correspond to the Maya "Joint Orient" attribute values. I think a possible solution is to freeze the joint orientations so they are 0,0,0 for the entire skeleton, and then perhaps there won't be a need for Pre or Post Rotation...

    And then Reimporting the FBX with Resample Curves = False.

    Good news: the curves now match in Maya and Unity.
    Bad news: Unity has added additional keyframes not present in Maya, and the resulting animation when played back looks incorrect because of the lack of Pre and Post Rotations :(

    This screenshot shows the curve in Maya and Unity. Note: for the Unity curve, the keyframes from Maya are highlighted in yellow. I would expect that these would be the ONLY keyframes that show up in Unity, but as you can see there are additional keyframes added during import:

     
    Last edited: Mar 29, 2020
  8. Brad-Newman

    Brad-Newman

    Joined:
    Feb 7, 2013
    Posts:
    156
    I was able to finally get the keyframes in Maya to match in Unity. Indeed, freezing the joint orientations in Maya to be 0,0,0 does the trick. To get it to work, do the following:

    Maya
    1. Select all your joints that are skinned to the mesh.
    2. Modify > Freeze Transforms (Options)
      1. Rotate: On
      2. Scale: On
      3. Joint Orient: On
    3. (Optional: Most pipelines at this point would bake animation on the skinned joints to transfer the animation from the keyframed control curves. Depends on your situation).
    4. (Optional: I'm then simplifying my upper body curves a lot to optimize them, and only simplifying the legs a little bit.)
    5. Export the FBX to Unity (don't bake in the FBX export options)
    Unity
    1. Set the FBX Animation Import Options to:
      1. Resample Curves: Off
      2. Animation Compression: Off
    Now the resulting curves in Unity will not be resampled and the keyframes will match what is in Maya, ostensibly because the PreRotations are 0,0,0 / non-existent.

    To automate this process, use the following script:

    Code (CSharp):
    1. sing UnityEngine;
    2. using UnityEditor;
    3.  
    4. public class AnimProcessor : AssetPostprocessor
    5. {
    6.     void OnPreprocessAnimation()
    7.     {
    8.         ModelImporter modelImporter = assetImporter as ModelImporter;
    9.         modelImporter.resampleCurves = false;
    10.         modelImporter.animationCompression = ModelImporterAnimationCompression.Off;
    11.     }
    12. }
    Here are the matching curves from a simple test animation:

     
    Last edited: Mar 29, 2020
    kemijo, Naitved and Kybernetik like this.
  9. mattstrangio

    mattstrangio

    Joined:
    Dec 31, 2017
    Posts:
    4
    Very interesting. Thanks for posting this! Have you noticed any significant file size or speed/performance issues when doing this with your animations vs. the default Maya-to-Unity fbx?
     
unityunity