サークル獏の佐藤敏 Unityとか備忘録

サークル獏の佐藤敏がUnityとかで知ったTipsを書いておく備忘録です。

複数のfbxファイルからアニメーション(anim)を抽出&余計なAnimationEventを削除

tsubakit1.hateblo.jp
こちらのテラシュールブログさんの記事にfbxからanimを抽出する方法は掲載されているんですが、複数のfbxからアニメーション(anim)を抽出するパターンを。
あと、最初からAnimationEventがついていると再生時にエラーが出て鬱陶しいのでそれを削除するコードも入っています。

f:id:VinSatoo:20190502043534p:plain
AnimationEventが必要ない場合、放置するとこんなエラーが出るので。

やり方

Unity プロジェクトの「Editor」フォルダに追加
→Project画面のfbxファイルを(複数)選択し右クリック
→「AnimExtractor」を実行すると同じフォルダにanimが抽出されます。

大量のファイルを処理すると結構重いんで、最初は10個以下くらいから様子見してください。20~30個とかanimが含まれるfbxなら個別にやったほうがいいかもしれません。

コード

using UnityEngine;
using UnityEditor;
using System.IO;

public class AnimExtractor
{

	static string tempExportedClip = "Assets/tempClip.anim";
	static AnimationEvent[] emptyAnimationEventArray = new AnimationEvent[0];

	[MenuItem("Assets/AnimExtractor")]
	static void AssetCopy() {


		Object[] selectedAsset = Selection.GetFiltered(typeof(Object), SelectionMode.Assets);
		foreach (var go in selectedAsset) {
			ExtractFunc(go);
		}

		AssetDatabase.Refresh();
	}

	private static void ExtractFunc(Object obj) {
		string path = AssetDatabase.GetAssetPath(obj);
		string currentFolder = Path.GetDirectoryName(path);

		var animations = AssetDatabase.LoadAllAssetsAtPath(path);
		var originalClips = System.Array.FindAll<Object>(animations, item =>
			  item is AnimationClip
		);

		foreach(var clip in originalClips) {
			copyClip(clip, currentFolder);
		}
	}

	private static void copyClip(Object clip, string folder) {
		if (clip.name.StartsWith("__preview__"))
			return;

		var instance = Object.Instantiate(clip);
		AnimationClip copiedAnim = instance as AnimationClip;
		AnimationUtility.SetAnimationEvents(copiedAnim, emptyAnimationEventArray);  //AnimationEventを削除しなくていいならこの行を削除

		AssetDatabase.CreateAsset(copiedAnim, tempExportedClip);
		string exportPath = folder + "/" + clip.name + ".anim";

		if(File.Exists(exportPath))
			exportPath = AssetDatabase.GenerateUniqueAssetPath(exportPath);

		File.Copy(tempExportedClip, exportPath, true);
		File.Delete(tempExportedClip);
	}
}