//Created by Neodrop
//Batch Extract/Attach by Tsar4k
//neodrop@unity3d.ru
// Based on http://answers.unity3d.com/questions/65 ... -animation
using UnityEditor;
using UnityEngine;
class AnimationTools4k : MonoBehaviour
{
const string duplicatePostfix = ""; // "_copy";
static void CopyClip(string importedPath, string copyPath)
{
AnimationClip src = AssetDatabase.LoadAssetAtPath(importedPath, typeof(AnimationClip)) as AnimationClip;
AnimationClip newClip = new AnimationClip();
newClip.name = src.name + duplicatePostfix;
AssetDatabase.CreateAsset(newClip, copyPath);
AssetDatabase.Refresh();
}
static void ExtractAnimationsCopyClip(AnimationState state, string newName, string copyPath)
{
// Get selected AnimationClip
AnimationClip imported = state.clip as AnimationClip;
if (imported == null)
{
Debug.Log("Selected object is not an AnimationClip");
return;
}
// Find path of copy
string importedPath = AssetDatabase.GetAssetPath(imported);
copyPath += "/" + newName + ".anim";
CopyClip(importedPath, copyPath);
AnimationClip src = AssetDatabase.LoadAssetAtPath(importedPath, typeof(AnimationClip)) as AnimationClip;
AnimationClip newClip = new AnimationClip();
newClip.name = src.name + duplicatePostfix;
AssetDatabase.CreateAsset(newClip, copyPath);
// AssetDatabase.Refresh();
AnimationClip copy = AssetDatabase.LoadAssetAtPath(copyPath, typeof(AnimationClip)) as AnimationClip;
if (copy == null)
{
Debug.Log("No copy found at " + copyPath);
return;
}
// Copy curves from imported to copy
AnimationClipCurveData[] curveDatas = AnimationUtility.GetAllCurves(imported, true);
for (int i = 0; i < curveDatas.Length; i++)
{
AnimationUtility.SetEditorCurve(
copy,
curveDatas[i].path,
curveDatas[i].type,
curveDatas[i].propertyName,
curveDatas[i].curve
);
}
}
[MenuItem("Assets/Animation Tools/Extract All Animations To Folder")]
static void ExtractAnimations()
{
System.IO.DirectoryInfo dif = new System.IO.DirectoryInfo(Application.dataPath.Replace("Assets", "") + AssetDatabase.GetAssetPath(Selection.activeObject));
System.IO.FileInfo[] finfo = dif.GetFiles("*.fbx");
if (finfo.Length == 0)
{
Debug.Log(".FBX files not found in selected folder");
return;
}
string folderForAnimation = Application.dataPath.Replace("Assets", "") + AssetDatabase.GetAssetPath(Selection.activeObject) + "_AnimationsOnly";
System.IO.Directory.CreateDirectory(folderForAnimation);
string copyPathFolder;
/*
copyPathFolder = EditorUtility.OpenFolderPanel("Select folder for extract .anim from .FBX", folderForAnimation, "");
if (copyPathFolder == "") { return; };
Debug.Log(copyPathFolder);
*/
copyPathFolder = AssetDatabase.GetAssetPath(Selection.activeObject) + "_AnimationsOnly";
AssetDatabase.Refresh();
int unusedPath = Application.dataPath.Length - 6;
System.Collections.Generic.List<string> animationsToLoad = new System.Collections.Generic.List<string>();
System.Collections.Generic.List<string> animationsDublicate = new System.Collections.Generic.List<string>();
System.Collections.Generic.List<string> animationsToLoadLog = new System.Collections.Generic.List<string>();
System.Collections.Generic.List<string> filesWitoutAnimations = new System.Collections.Generic.List<string>();
int animationsCounFull = 0;
for (int i = 0; i < finfo.Length; i++)
{
GameObject currentFbx = AssetDatabase.LoadAssetAtPath(finfo[i].FullName.Remove(0, unusedPath), typeof(GameObject)) as GameObject;
animationsToLoadLog.Add("File " + i + " " + finfo[i].FullName);
animationsToLoadLog.Add("");
int animationsCounLocal = 0;
foreach (AnimationState state in currentFbx.GetComponent<Animation>())
{
string newName = state.name;
if (state.name.StartsWith("Take "))
{
newName = currentFbx.name + "_" + state.name;
}
string animationHolder = Application.dataPath.Replace("Assets", "") + AssetDatabase.GetAssetPath(state.clip);
if (System.IO.Path.GetFileName(finfo[i].FullName) == System.IO.Path.GetFileName(animationHolder))
{
ExtractAnimationsCopyClip(state, newName, copyPathFolder);
animationsToLoadLog.Add(" +Anim " + animationsCounLocal + " " + newName);
animationsToLoad.Add(newName);
animationsCounLocal++;
}
else
{
animationsToLoadLog.Add(" -Anim " + animationsCounLocal + " " + newName);
animationsToLoadLog.Add(" realFile " + System.IO.Path.GetFileName(animationHolder));
animationsDublicate.Add(newName);
animationsCounLocal++;
}
animationsToLoadLog.Add("");
animationsToLoadLog.Add("");
// Debug.Log(newName);
}
if (animationsCounLocal == 0)
{
filesWitoutAnimations.Add(System.IO.Path.GetFileName(finfo[i].FullName));
}
animationsCounFull += animationsCounLocal;
}
animationsToLoad.Sort();
animationsDublicate.Sort();
System.IO.StreamWriter animationsFileStream = new System.IO.StreamWriter(copyPathFolder + "/_AnimationsToLoadList.txt");
foreach (string animationName in animationsToLoad)
{
animationsFileStream.WriteLine(animationName);
}
animationsFileStream.Close();
animationsFileStream = new System.IO.StreamWriter(copyPathFolder + "/_AnimationsExtractorLog.txt");
foreach (string animationName in animationsToLoadLog)
{
animationsFileStream.WriteLine(animationName);
}
animationsFileStream.WriteLine("");
animationsFileStream.WriteLine("Total Animations Checked " + animationsCounFull);
animationsFileStream.WriteLine("Total Animations Exported " + animationsToLoad.Count + " see _AnimationsToLoadList.txt file");
animationsFileStream.WriteLine("");
animationsFileStream.WriteLine("Dublicates " + animationsDublicate.Count);
animationsFileStream.WriteLine("Dublicate List");
animationsFileStream.WriteLine("");
foreach (string animationName in animationsDublicate)
{
animationsFileStream.WriteLine(animationName);
}
animationsFileStream.WriteLine("");
animationsFileStream.WriteLine("Total FBX Files Checked " + finfo.Length);
animationsFileStream.WriteLine("Without Animations " + filesWitoutAnimations.Count);
animationsFileStream.WriteLine("");
animationsFileStream.WriteLine("Files without Animations List");
animationsFileStream.WriteLine("");
foreach (string fileName in filesWitoutAnimations)
{
animationsFileStream.WriteLine(fileName);
}
animationsFileStream.Close();
AssetDatabase.Refresh();
}
[MenuItem("Assets/Animation Tools/UnLink Animation", true)]
static bool CopyCurvesToDuplicateValidator()
{
return Selection.activeObject.GetType() == typeof(AnimationClip);
}
[MenuItem("Assets/Animation Tools/UnLink Animation")]
static void CopyCurvesToDuplicate()
{
// Get selected AnimationClip
AnimationClip imported = Selection.activeObject as AnimationClip;
if (imported == null)
{
Debug.Log("Selected object is not an AnimationClip");
return;
}
// Find path of copy
string importedPath = AssetDatabase.GetAssetPath(imported);
string copyPath = importedPath.Substring(0, importedPath.LastIndexOf("/"));
copyPath += "/" + imported.name + ".anim";
CopyClip(importedPath, copyPath);
AnimationClip copy = AssetDatabase.LoadAssetAtPath(copyPath, typeof(AnimationClip)) as AnimationClip;
if (copy == null)
{
Debug.Log("No copy found at " + copyPath);
return;
}
// Copy curves from imported to copy
AnimationClipCurveData[] curveDatas = AnimationUtility.GetAllCurves(imported, true);
for (int i = 0; i < curveDatas.Length; i++)
{
AnimationUtility.SetEditorCurve(
copy,
curveDatas[i].path,
curveDatas[i].type,
curveDatas[i].propertyName,
curveDatas[i].curve
);
}
}
[MenuItem("Assets/Animation Tools/Attach All Animations From Folder")]
static void AttachAllAnimations()
{
GameObject gameObjectToAnimate = Selection.activeObject as GameObject;
if (gameObjectToAnimate == null)
{
Debug.Log("Selected object is not an GameObject");
return;
}
if (gameObjectToAnimate.GetComponent<Animation>() == null)
{
Debug.Log("Selected object is GameObject but not have Animation component (to add do: Component -> Miscellanious -> Animation)");
return;
}
string animationFolderPath = EditorUtility.OpenFolderPanel("Load .anim of Directory", Application.dataPath, "");
if (animationFolderPath == "") { return; };
System.IO.DirectoryInfo dif = new System.IO.DirectoryInfo(animationFolderPath);
System.IO.FileInfo[] finfo = dif.GetFiles("*.anim");
if (finfo.Length == 0)
{
Debug.Log(".anim files not found in selected folder");
return;
}
int unusedPath = Application.dataPath.Length - 6;
for (int i = 0; i < finfo.Length; i++)
{
AnimationClip currentClip = AssetDatabase.LoadAssetAtPath(finfo[i].FullName.Remove(0, unusedPath), typeof(AnimationClip)) as AnimationClip;
gameObjectToAnimate.animation.AddClip(currentClip, currentClip.name);
Debug.Log(i+" - animation "+ currentClip.name + " added");
AssetDatabase.Refresh();
}
}
}