最近有个新需求,要用代码添加动画的事件,但是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动画使用GetCurveBindings、GetEditorCurve和SetEditorCurve方法
Legacy要使用GetObjectReferenceCurveBindings、GetObjectReferenceCurve和SetObjectReferenceCurve方法
那么单个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再点击扩展的菜单栏按钮就可以了