最近由于项目需要,要将以前实现ui动画的animator全部改为animation组件。
思路:(1)获取目标路径内的所有object路径,在场景内生成ui预制体,查找并替换所有animator为animation,删除原prefab,由场景内的gameobject在原文件位置生成同名预制体,保存。
(2)由于animator使用的animationclip的legacy属性为false,不能再animation上使用,又由于手动在debug界面上修改此值,运行一次后会还原,故将所有animationclip使用代码复制一份并设置legacy,删除原clip并在原文件位置保存。
以下为代码:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.IO;
using UnityEditor;
public class Animator2Animation : MonoBehaviour {
// Use this for initialization
void Start () {
Invoke("ChangeClipForAnimation", 3);
}
///
/// 将目录内所有的animationClip复制一份,将其legacy设置为true,保存同名clip并删除旧的animationclip
///
public void ChangeClipForAnimation()
{
print("change Clip start !!!");
//获取所有object的路径
string[] allPath = Directory.GetFiles(Application.dataPath + "/animator2animation", "*", SearchOption.AllDirectories);
//循环遍历每一个路径,单独加载
foreach (string strobjPath in allPath)
{
if (strobjPath.EndsWith(".anim"))
{
//替换路径中的反斜杠为正斜杠
string strTempPath = strobjPath.Replace(@"\", "/");
//截取我们需要的路径
strTempPath = strTempPath.Substring(strTempPath.IndexOf("Assets"));
//根据路径加载资源
Object obj = AssetDatabase.LoadAssetAtPath(@strTempPath, typeof(Object));
AnimationClip clip = obj as AnimationClip;
AnimationClip newclip = new AnimationClip();
newclip.name = clip.name;
newclip.legacy = true;
AnimationClipSettings clipSetting = AnimationUtility.GetAnimationClipSettings(clip);//获取AnimationClipSettings
AnimationUtility.SetAnimationClipSettings(newclip, clipSetting);//设置新clip的AnimationClipSettings
newclip.frameRate = clip.frameRate;//设置新clip的帧率
EditorCurveBinding[] curveBindings = AnimationUtility.GetCurveBindings(clip);//获取clip的curveBinds
for (int i = 0; i < curveBindings.Length; i++)
{
AnimationUtility.SetEditorCurve(newclip, curveBindings[i], AnimationUtility.GetEditorCurve(clip, curveBindings[i]));//设置新clip的curve
}
GameObject.DestroyImmediate(clip, true);
strTempPath = strTempPath.Substring(0, strTempPath.LastIndexOf('/'));
AssetDatabase.CreateAsset(newclip, strTempPath + "/" + newclip.name + ".anim");
}
}
print("change clip over!!!");
}
///
/// 此方法会:(1)将目录内所有的prefab在场景内生成,查找其包含的animator并修改为animation,将原prefab删除并在原位置生成新的同名prefab
/// (2)将目录内所有的animationClip复制一份,将其legacy设置为true,保存同名clip并删除旧的animationclip
///
public void AnimatorTurnToAnimation()
{
print("Animator to Animation start !!!");
//获取所有object的路径
string[] allPath = Directory.GetFiles(Application.dataPath + "/YLResources/Prefabs/UI", "*", SearchOption.AllDirectories);
//循环遍历每一个路径,单独加载
foreach (string strobjPath in allPath)
{
if (strobjPath.EndsWith(".prefab"))
{
bool needsave = false;
//替换路径中的反斜杠为正斜杠
string strTempPath = strobjPath.Replace(@"\", "/");
//截取我们需要的路径
strTempPath = strTempPath.Substring(strTempPath.IndexOf("Assets"));
//根据路径加载资源
Object obj = AssetDatabase.LoadAssetAtPath(@strTempPath, typeof(Object));
GameObject prefab = obj as GameObject;
GameObject newprefab = Instantiate(prefab) as GameObject;
newprefab.name = prefab.name;
Animator animator = newprefab.GetComponent();
if (animator != null)
{
needsave = true;
Change(animator);
}
Animator[] animators = newprefab.GetComponentsInChildren(true);
if (animators != null && animators.Length > 0)
{
needsave = true;
foreach (Animator item in animators)
{
Change(item);
}
}
if (needsave == true)
{
GameObject.DestroyImmediate(prefab, true);
strTempPath = strTempPath.Substring(0, strTempPath.LastIndexOf('/'));
//AssetDatabase.CreateAsset(newprefab, strTempPath + "/" + newprefab.name + ".prefab");
PrefabUtility.CreatePrefab(strTempPath + "/" + newprefab.name + ".prefab", newprefab);
LoggerHelper.Debug(strTempPath + "/" + newprefab.name + ".prefab");
}
GameObject.DestroyImmediate(newprefab);
}
}
foreach (string strobjPath in allPath)
{
if (strobjPath.EndsWith(".anim"))
{
//替换路径中的反斜杠为正斜杠
string strTempPath = strobjPath.Replace(@"\", "/");
//截取我们需要的路径
strTempPath = strTempPath.Substring(strTempPath.IndexOf("Assets"));
//根据路径加载资源
Object obj = AssetDatabase.LoadAssetAtPath(@strTempPath, typeof(Object));
AnimationClip clip = obj as AnimationClip;
//if (clip.legacy == false)
//{
AnimationClip newclip = new AnimationClip();
newclip.name = clip.name;
newclip.legacy = true;
AnimationClipSettings clipSetting = AnimationUtility.GetAnimationClipSettings(clip);//获取AnimationClipSettings
AnimationUtility.SetAnimationClipSettings(newclip, clipSetting);//设置新clip的AnimationClipSettings
newclip.frameRate = clip.frameRate;//设置新clip的帧率
EditorCurveBinding[] curveBindings = AnimationUtility.GetCurveBindings(clip);//获取clip的curveBinds
for (int i = 0; i < curveBindings.Length; i++)
{
AnimationUtility.SetEditorCurve(newclip, curveBindings[i], AnimationUtility.GetEditorCurve(clip, curveBindings[i]));//设置新clip的curve
}
GameObject.DestroyImmediate(clip, true);
strTempPath = strTempPath.Substring(0, strTempPath.LastIndexOf('/'));
AssetDatabase.CreateAsset(newclip, strTempPath + "/" + newclip.name + ".anim");
//}
}
}
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
print("Animator to Animation end!");
}
public static void Change(Animator animator)
{
RuntimeAnimatorController ac = animator.runtimeAnimatorController;
if (ac != null)
{
AnimationClip[] tAnimationClips = ac.animationClips;
if (tAnimationClips != null && tAnimationClips.Length > 0)
{
Animation animation = animator.gameObject.GetComponent(true);
foreach (AnimationClip clip in tAnimationClips)
{
//不改成true无法添加到animation组件上,但是改动了以后运行一次又会还原,所以只能代码创建新的同名clip,把数据复制进去同时将此值设为true,再将原clip删除就可以了
clip.legacy = true;
animation.AddClip(clip, clip.name);
}
GameObject.DestroyImmediate(animator, true);
}
}
}
}