Unity Editor Scripts for creating animation assets and "reducing" facefx_loop_anim for Evolver characters

I wrote two tiny little editor scripts for Unity that I felt might be useful for other people, too.

Use case:

a) I want the animations that FaceFXImportXMLActor adds to the character that has FaceFXControllerScript attached to be available as assets in my project. This makes it easier for me to edit the animations or properly put them into version control, if I need to. Furthermore, this makes it possible to create proper prefabs (with animations that are not in the project, the animations are only available in the prefab instance you imported the animations on, not the prefab itself). This is done in DoCreateAnimationAssets() which you can call through the menu Assets/Create Animation Assets when you put the script below in the "Editor" folder. You might need to create the folder "AnimationClips" in the root of your Unity project (not sure if that's auto-created if it's not there, yet - otherwise, you'd get an error message).

b) I'm mixing full body animations from other sources (idle, sit etc.) with the FaceFX lip-sync animations. For that purpose, facefx_loop_anim must not animate any bones except for the facial bones, so instead of having to click about a gazillion times to remove all those dead animations manually, I've created an editor script. This one is dangerous - only touch it if you know what you're doing; don't blame me if you used it one some animation and then it doesn't work anymore because you deleted too much ;-) ... but if you know your animations (check them in the animation editor first), and precisely understand what the code does, this may be useful for you. The way I use this: First, I use "Create Animation Assets" to get an animation asset called facefx_loop_anim (in the folder AnimationClips). I select this asset in the project view. With facefx_loop_anim selected, I use the menu Assets/Fix facefx_loop_anim ... and then I can happily mix body and facial animations ;-)

So here's the code (hopefully that comes across correctly in the forum):


using UnityEngine;
using UnityEditor;
using System.Collections;

public class CreateAnimationAssets : MonoBehaviour {

[MenuItem("Assets/Create Animation Assets")]
static void DoCreateAnimationAssets() {
if (Selection.activeGameObject.GetComponent() != null) {
Animation anim = Selection.activeGameObject.GetComponent();
foreach (AnimationState animClip in anim) {
AssetDatabase.CreateAsset(animClip.clip, string.Format("Assets/AnimationClips/{0}.anim", animClip.name));
}
}
}

[MenuItem("Assets/Fix facefx_loop_anim")]
static void DoFixFaceFXLoopAnim() {
if (Selection.activeObject != null && Selection.activeObject is AnimationClip) {
AssetDatabase.StartAssetEditing();
AnimationClip selectedClip = (AnimationClip) Selection.activeObject;

AnimationClipCurveData[] curves = AnimationUtility.GetAllCurves(selectedClip);
foreach (AnimationClipCurveData curve in curves) {
if (!curve.path.Contains("Neck")) {
for (int i = curve.curve.keys.Length - 1; i >= 0; i--) {
curve.curve.RemoveKey(i);
}
string propertyName = curve.propertyName;
// we can't delete "*.x", e.g. m_LocalScale.x - but only "*", e.g. m_LocalScale
if (propertyName.IndexOf(".") > 0) {
propertyName = propertyName.Substring(0, propertyName.IndexOf("."));
}
Debug.Log(string.Format("Fixing: {0} - {1}", curve.path, propertyName));
selectedClip.SetCurve(curve.path, curve.type, propertyName, null);
}
}
AssetDatabase.StopAssetEditing();
}
}

}

Feel free to comment (there might be better ways of doing this).

Permalink

Thanks for this!

The loop animation is only played on the "FaceFX Reference Bones" The evolver sample content includes all bones in the reference pose, but if you have other animations playing, then you will only want the face bones there.

To fix, I opened up the EvolverActorFile.xml and deleted the unwanted bones from the reference pose. Then I opened the XML file up in studio, deleted the empty bone poses, and re-exported the XML to get a clean version.

You could also do this from the plugins by simply exporting a new reference pose at a frame where the character is in the neutral position. When you export a new reference pose, it's always a good idea to batch-export all of your bone poses (especially if you have added bones to the reference pose).

I'll add the new XML file in the next drop!