Unity——用UnityEditor拷貝FBX中的AnimationClip

最近有個新需求,要用代碼添加動畫的事件,但是Unity不能直接修改FBX中的AnimationClip

 

在Animation窗口中可以看到,AnimationClip是Read-Only狀態,用代碼修改這個AnimationClip也是不會生效的,包括用代碼添加事件

 

解決方法就是將這個AnimationClip從FBX中複製一份,如果不用代碼的話,就是選中這個AnimationClip然後按Ctrl+D

AnimationClip已經被複製出來了

 

但是大量的動畫文件,肯定不能用這種方法解決,還是要用代碼批量處理

複製代碼

 1  static void AnimCopy(string fbxPath, string parentPath, string name)
 2     {
 3         Object[] objs = AssetDatabase.LoadAllAssetsAtPath(fbxPath);
 4 
 5         string animationPath = "";
 6 
 7         AnimationClipSettings setting;
 8 
 9         AnimationClip srcClip;//源AnimationClip
10 
11         AnimationClip newClip;//新AnimationClip
12 
13         foreach (Object o in objs)
14         {
15             if (o.GetType() == typeof(AnimationClip) && o.name == name)
16             {
17                 srcClip = o as AnimationClip;
18 
19                 newClip = new AnimationClip();
20 
21                 newClip.name = srcClip.name;//設置新clip的名字
22 
23                 if (!Directory.Exists(parentPath + @"/copy/"))
24 
25                     Directory.CreateDirectory(parentPath + @"/copy/");
26 
27                 animationPath = parentPath + @"/copy/" + newClip.name + ".anim";
28 
29                 setting = AnimationUtility.GetAnimationClipSettings(srcClip);//獲取AnimationClipSettings
30 
31                 AnimationUtility.SetAnimationClipSettings(newClip, setting);//設置新clip的AnimationClipSettings
32 
33                 newClip.frameRate = srcClip.frameRate;//設置新clip的幀率
34 
35                 EditorCurveBinding[] curveBindings = AnimationUtility.GetCurveBindings(srcClip);//獲取clip的curveBinds
36 
37                 for (int i = 0; i < curveBindings.Length; i++)
38                 {
39                     AnimationUtility.SetEditorCurve(newClip, curveBindings[i], AnimationUtility.GetEditorCurve(srcClip, curveBindings[i]));//設置新clip的curve
40                 }
41 
42                 AssetDatabase.CreateAsset(newClip, animationPath); //AssetDatabase中的路徑都是相對Asset的  如果指定路徑已存在asset則會被刪除,然後創建新的asset
43 
44                 AssetDatabase.SaveAssets();//保存修改
45 
46                 AssetDatabase.Refresh();
47 
48             }
49         }
50     }

複製代碼

上面的代碼就是將FBX中的動畫文件的數據設置到一個新的AnimationClip上

 

需要注意的是,Unity中有兩種AnimationClip

第一種是直接右鍵Create-Animation直接創建

創建後選擇Debug

可以看到Legacy選項沒有選上

 

第二種是選擇場景中的一個物體,然後打開Animtion窗口,可以看到出現了Create按鈕

同樣創建後選擇Debug可以看到

這種動畫的Legacy選項是被勾選的

 

具體的區別就不說了,不過在上面的代碼中有這樣一段

1               EditorCurveBinding[] curveBindings = AnimationUtility.GetCurveBindings(srcClip);//獲取clip的curveBinds
2 
3             for (int i = 0; i < curveBindings.Length; i++)
4                {
5                  AnimationUtility.SetEditorCurve(newClip, curveBindings[i], AnimationUtility.GetEditorCurve(srcClip, curveBindings[i]));//設置新clip的curve
6               }

非Legacy動畫使用GetCurveBindingsGetEditorCurveSetEditorCurve方法

Legacy要使用GetObjectReferenceCurveBindingsGetObjectReferenceCurveSetObjectReferenceCurve方法

 

那麼單個AnimationClip複製已經完成了,接下來就是批量的複製

複製代碼

 1 [MenuItem("CYL/CopyAnimationClip")]
 2     public static void AnimationClipsCopy()
 3     {
 4         Object[] go = Selection.objects;
 5 
 6         string Path = AssetDatabase.GetAssetPath(go[0]);
 7 
 8         string parentPath = Editor_Ani.getParentPathForAsset(Path);
 9 
10         for (int i = 0; i < go.Length; i++)
11         {
12             string fbxPath = AssetDatabase.GetAssetPath(go[i]);
13 
14             AnimCopy(fbxPath, parentPath, go[i].name.Split('@')[1]);
15         }
16     }
17 
18 
19 
20     /// <summary>
21     /// 返回傳入目錄的父目錄(相對於asset)
22     /// </summary>
23     /// <param name="assetPath"></param>
24     /// <returns></returns>
25     public static string getParentPathForAsset(string assetPath)
26     {
27         string[] pathName = assetPath.Split('/');
28         string parentPath = "";
29 
30         if (pathName.Length < 2 || pathName[pathName.Length - 1] == "")
31         {
32             Debug.Log(assetPath + @"沒有父目錄!");
33             return parentPath;
34         }
35 
36         for (int i = 0; i < pathName.Length - 1; i++)
37         {
38 
39             if (i != pathName.Length - 2)
40                 parentPath += pathName[i] + @"/";
41             else
42                 parentPath += pathName[i];
43         }
44 
45         return parentPath;
46     }

複製代碼

選中所有的FBX再點擊擴展的菜單欄按鈕就可以了

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章