SkillAgentSearch skills...

AnimationMemoryUsageInUnity

A repository for the test project to research the different Memory usage of properly and improperly optimized animations.

Install / Use

/learn @razluta/AnimationMemoryUsageInUnity
About this skill

Quality Score

0/100

Supported Platforms

Zed

README

Animation Memory Usage in Unity License

Best Practices for Optimizing Animation Memory Usage - This repository attempts to best analyze all possible outcomes that could result in less than optimal memory usage when bringing in different types of 3D animations into Unity. While animations are not typically the most memory-intensive assets in a project, many 3D mobile games are very animation heavy, and, as such ,animation represents a significant part of the data that needs optimization.

Conclusions

This section summarizes all conclusions reached after studying the data.

Summary

It is best to use complex rigs (as complex they need to be to achieve the animation in the DCC package) to generate simple single hierarchy rig skeletons and animations with the minimum amount of keys possible and import it in Unity using the Animation Compression set to Optimal. Use the Animation Masking feature to further reduce the size of the animation in the build.

The delta between the most optimized and least optimized situation presented in this test, for the same animation, was over 500 KB. If the project has a conservative 20 animations per each character and 10 characters loaded at the same time, that could result in almost 100 MB of wasted runtime memory, which on a low end device such as the iPhone 6s represents a large chunk of the usable memory (and this is worrisome because, for 3D projects, textures typically present an even bigger threat to excessive memory usage and could exceed the limits if the animations are also bulky).

Detailed Explanation

To best optimize and minimize the memory usage of an animation clip, the following are universally recommended:

  1. The skeleton/rig used to create/define the Unity Avatar should contain the rig and the mesh, but no animation. The image below showcases a full complex rig with its hierarchy on the left side and a "simplified"/single hierarchy rig (ready for export to Unity on the right side).

Taking a step forward, the right side of the image above is continued in the image below where it exemplifies a skeleton .fbx file that only contains the model and the single hierarchy chain rig (as seen in Unity).

  1. The Avatar generated from the rig should be used for all animations that are supposed to share that rig (unless there is an explicit need for a new Avatar, for example, having to use animations that were not created on/for this rig with this rig), otherwise, each animation will end up with its own avatar and will cost additional memory usage. To use an existent Avatar for an animation, the user needs to define it in the import options for the animations as demonstrated in the image below. It is very important to only create one Avatar for a rig/character setup. The original skeleton + mesh(es) used to create the Avatar need to contain everything needed to achieve all necessary motion or deformation for that rig. All animations intended to work with the rig need only to be pointed to the existing Avatar. By failing to do this setup, the user incurs an added cost for the new Avatar, but may additionally incur cost for extrenous data not being eliminated from the animation file (such as a mesh that should not exist or be ignore or such as rig controllers).

  1. No single animation file should contain the mesh. Each animation should only contain the rig joints and the animation(s) on them (speaking strictly about the exported / published file, not the animation source file). As demonstrated in the examples in the repository, having the mesh in the animation file does not increase the animation size in memory in the built project (because only the animation data is used to generate the Unity Animation Clip), but it considerably increases the animation file size on disk. In this example, the size delta is about 300 KB per file. Multiply that by 50 animations per character, in a project of 100 characters, that is over 1.4 GB of wasted space. Additionally, having the mesh in the animation file presents the added risk of accidentally using that mesh in the game in a scene, at which point Unity would have a duplicate of that mesh in memory and the actual runtime memory will also increase by 300 KB times the number of accidents. The image below exemplifies an animation .fbx file that only contains the single hierarchy chain rig with animation on it. It is important to note that the animation is not visible in the scene preview window when dragged directly in the scene because it needs to be applied to an already created Avatar.

In the test data, we have built two projects: one with the animation with no mesh and one with the animation with the same mesh. The results are as follows:

  • the build size for both projects was 27609 KB
  • the animation without the mesh was 750 KB on disk, while the animation with the mesh was 1033 KB on disk
  • the animation clip (1) for both was 17 KB in the runtime memory
  • the mesh (1) for both was 372.3 KB in runtime Memory

Conclusions:

  • even if the mesh exists in the animation file, as long as an already existing Avatar is being used (as opposed to a new one being generated), the mesh will not be duplicated in memory and ignored
  • although having a mesh in the animation might not impact the runtime memory, it may increase size on disk (project size), import times and general editor performance

Although not universally applicable, we recommend the following settings (unless advanced users have tested and profiled specialized branching from these standards): 1.If the goal is to minimize memory, Anim. Compression should be set to Optimal. For mobile games and application, Optimal is most likely the best choice for any animations that are used for gameplay (cinematic animations could be less compressed, if needed). The three animation compression options are: "Off", "Optimal" and "Keyframe Reduction". In most cases, "Optimal" is the option best suited for the best animation compression resulting in a smaller memory footprint. Optimal will attempt keyframe reduction, but will result in a lower quality animation asn it has worse overall in-between frames (less memory at the cost of worse interpolation in between keys). Fine tuning each setting for each animation may provide better results, but it is likely a solution that cannot scale for hundreds of animations. In this demo, almost across the board, using the "Optimal" setting provided significant Memory reduction. Below are a few of the examples:

  • the short walk animation using keyed poses only and imported using "Optimal" compression was 17 KB <> using the "Keyframe Reduction" option, the same animation was 43.6 KB <> using the "Off" option (no compression), the same animation was 70 KB
  • the long walk animation using all keys baked and imported using "Optimal" compression was 103 KB <> using the "Keyframe Reduction" option, the same animation was 293.6 KB <> using the "Off" option (no compression), the same animation was 614 KB As observed in the examples, above, the difference can be 500 KB on a long (300 frames) animation, which can quickly add up.

Additionally, here are some common mistakes when working with animation data coming from DCC packages.

  1. Each of the rig and the animation .fbx files should only contain what is commonly referred to as the single hierarchy joint chain. Typically, animation rigs are very complex in the DCC package to allow the animator extensive control over the "base" skeleton. This complex setup usually contains IK (inverse kinematics) controllers and setup, FK (forward kinematic) controllers and setup, helper nodes, etc. Some of these nodes are nodes that are supported by the .fbx format and when accidentally exported, will create empty GameObjects in the Unity hierarchy, but will still contain the animation data and waste memory resources. We recommend exporting only the single hierarchy joint chain for both the skeleton/rig (used to generate the Avatar), while for the animation, we recommend exporting only joints that are skinned to the mesh and used directly in the motion (no helper joints) - this process typically requires a standardization (naming or expected content/nodes) across rigs and an automated solution that can differentiate between what is needed in the game engine and what is not needed. It is important to note that when importing the animation as a Humanoid extraneous data might be cleaned up by the system because of the Humanoid bone mapping discarding the junk data, but the same junk data may persist in a Generic import. It is recommended to eliminate the risk by not having it at all. Below is some data from this analysis that backs up this claim:
  • when exported with only the single hierarchy rig and imported as a Humanoid, the skeleton was 42.5 KB <> when exported with the full rig and imported as a Humanoid, the skeleton was 46.3 KB
  • when exported with only the single hierarchy rig and imported with optimal compression, the short walk animation with all keys baked was 17 KB <> when exported with only the full rig and imported with optimal compression, the short walk animation with all keys baked was 70 KB
  1. Animations should not be set to bake all keyframes on export or be pre-baked in the original source animation file. If an animation is pre-baked on all keyframes in the original source file, it is very difficult to update and iterate on the file. Additionally, it automatically means the exported result will be baked as well. Similarly, if an animation is set to be baked on expor

Related Skills

View on GitHub
GitHub Stars23
CategoryEducation
Updated1y ago
Forks4

Security Score

75/100

Audited on Feb 27, 2025

No findings