During the development of “Animation Viewer”, I’ve encountered several issues that I want to document here.

How Animation Viewer was born

Animation Viewer was created by accident while I was working on my project, ComboGestureExpressions 2 (also tentatively called ComboGestureDynamics).

I wanted to make it easy to drag-and-drop animations into the CGE UI, but one problem stood, is that the user cannot see the animation before it is dropped into the CGE UI.

At that point, I already had a system to generate previews on animations on an animator, but it was used inside CGE UI.

So, I was looking for ways to generate previews on animations directly in the Project View.

Failed approach using RenderStaticPreview

I tried to create a custom Editor for the AnimationClip type.

By implementing an Editor, I was hoping to override the RenderStaticPreview method in order to bake the animation preview to be rendered in the project view just like materials. However, that did not go as planned:

RenderStaticPreview somehow updates little thumbnail that can be seen in the Inspector, but for some reason the thumbnails of the assets themselves were not getting updated.

Returning a new Texture2D would cause the animation asset not to change. However, returning the Texture2D that is returned by AssetPreview.GetMiniTypeThumbnail would result in a blank icon for some reason.

In addition, there were numerous crashes that I could not explain.

During my searches for a solution, I found and settled on the current approach using the EditorApplication.projectWindowItemOnGUI callback, which went well. In this approach, I use the callback to add items to a queue, and when items are added to a queue, a new task is scheduled for the next frame to actually render the queued items into their newly allocated texture.

Workaround: Animator moves to origin

In order to generate the preview, I copy the entire Animator hierarchy, hide the original, render the several animations using the copy, delete the copy, and then show the original again.

The expected result is that the copy is animated in-place. However, for a reason I cannot explain, the animator actually moves to the origin of the world after the first sampling. This is despite the animator having no RootT or RootQ properties in them.

In order to fix this, I record the position and rotation of the copy, and then apply that position again manually after the sampling ends.

Workaround: Muscles are not updated

When an animation is sampled, for some reason, the muscles of the animator will not update on subsequent AnimatorMode samplings on the same frame. This causes all animation thumbnails to have the same muscles positions, which is incorrect.

In order to fix this, I’ve found through trial and error that disabling the GameObject of the Animator and re-enabling it again on the same frame, does work around that issue.