Unity 2021.3.6
概要
Blender等の3DCGソフトでモデルのアニメーションを更新したあと、Unityに持っていく時に毎回以下の作業を実施している。
- UnityのAssetフォルダ配下のFBXファイルを直接上書き保存
- UnityのProjectパネルからFBXを開き、アニメーションを選択してCTRL + Dで抜き出し
- ファイルエクスプローラ等から操作して既存のAnimationClipに上書き保存
問題点として、3の操作をした際に既存のAnimationClipに設定したLoopやAnimationEventなどの情報が消えてしまう。
(結構な問題だと思うけど、言及してる人がほとんど居ないのは何故…)
この問題を解消するためにFBX内のアニメーションのCurve情報のみ既存のAnimationClipに上書きして保存するエディタ拡張を作った。
using System.IO;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
public class FBXAnimExtractor
{
static string exportAnimFolder = "Animations";
[MenuItem("Assets/Extract FBX Animations")]
static void AssetCopy() {
Object[] selectedAssets = Selection.GetFiltered(typeof(Object), SelectionMode.Assets);
foreach (var asset in selectedAssets) {
ExtractFunc(asset);
}
AssetDatabase.Refresh();
Debug.Log("FBXAnimExtractor Done.");
}
private static void ExtractFunc(Object obj) {
string path = AssetDatabase.GetAssetPath(obj);
string exportFolder = Path.Combine(Path.GetDirectoryName(path), exportAnimFolder);
if(!Directory.Exists( exportFolder )){
Directory.CreateDirectory( exportFolder );
}
var fbx = AssetDatabase.LoadAllAssetsAtPath(path);
var originalClips = System.Array.FindAll<Object>(fbx, item =>
item is AnimationClip
);
foreach(var clip in originalClips) {
copyClip(clip, exportFolder);
}
}
private static void copyClip(Object clip, string exportFolder) {
if (clip.name.StartsWith("__preview__"))
return;
var instance = Object.Instantiate(clip);
AnimationClip newAnim = instance as AnimationClip;
string clip_name = clip.name.Replace("|", "_") + ".anim"; // replace illegal character
string exportPath = Path.Combine(exportFolder, clip_name);
if(File.Exists(exportPath)){
var actions = new List<System.Action>();
var bindings = AnimationUtility.GetCurveBindings(newAnim);
AnimationClip existingAnim = (AnimationClip)AssetDatabase.LoadAssetAtPath(
exportPath, typeof(AnimationClip));
foreach (var binding in bindings)
{
var curve = AnimationUtility.GetEditorCurve(newAnim, binding);
var cb = binding;
actions.Add(() =>
{
AnimationUtility.SetEditorCurve(existingAnim, cb, curve);
});
}
existingAnim.ClearCurves();
foreach (var action in actions)
action.Invoke();
AssetDatabase.SaveAssets();
}else{
AssetDatabase.CreateAsset(newAnim, exportPath);
}
}
}
使い方
- Assets配下にEditorという名前のフォルダを作成(ビルド時に使用されない特殊なフォルダー名)
- UnityのProjectパネルから右クリック>Create>C# Scriptを選択してFBXAnimExtractorという名前のスクリプトファイルをEditorフォルダに作成
- 上記のコードをFBXAnimExtractorファイルにコピペして保存
- アニメーションを抜き出したいFBXを複数選択して右クリック>Extract FBX Animationsを選択
すると、FBXがあるフォルダ配下にAnimationsというフォルダが作られてその中にAnimationClipが新規作成または上書き保存されます。