如下是一个自动将prefab中的所有Animator都替换成Animation组件的功能,它会把所有animator中的clip自动挂载到Animation中的clip下;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using UnityEditor;
using UnityEngine;
public class GenerationAnimationWindow : EditorWindow {
[MenuItem("Assets/AnimationTools/GenerateAnimation", false, 1)]
public static void GenerationAnimation () {
var guids = Selection.assetGUIDs;
var prefabPath = AssetDatabase.GUIDToAssetPath(guids[0]);
var prefabAsset = AssetDatabase.LoadAssetAtPath<Object>(prefabPath);
var prefab = PrefabUtility.InstantiatePrefab(prefabAsset) as GameObject;
var animatorList = prefab.GetComponentsInChildren<Animator>();
for (int i = 0; i < animatorList.Length; i++){
var animator = animatorList[i];
var animationClips = animator.runtimeAnimatorController.animationClips;
var animation = animator.gameObject.GetComponent<Animation>();
if (animation != null){
GameObject.DestroyImmediate(animation);
}
animation = animator.gameObject.AddComponent<Animation>();
int count = 0;
for(int j = 0; j < animationClips.Length; j++){
animationClips[j].legacy = true;
ModifyAnimationClip(animationClips[j]);
animation.AddClip(animationClips[j], animationClips[j].name);
count++;
}
if (count == 1){
animation.clip = animationClips[0];
}
GameObject.DestroyImmediate(animator);
}
PrefabUtility.ApplyPrefabInstance(prefab, InteractionMode.UserAction);
GameObject.DestroyImmediate(prefab);
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
}
private static void ModifyAnimationClip(AnimationClip clip){
var path = AssetDatabase.GetAssetPath(clip);
StreamReader sr = new StreamReader(path);
string str = sr.ReadToEnd();
sr.Close();
string pattern = @"m_Legacy: \d";
Regex prefabSuffix = new Regex(pattern);
if(prefabSuffix.IsMatch(str)){
str = prefabSuffix.Replace(str, "m_Legacy: 1");
}
StreamWriter sw = new StreamWriter(path, false);
sw.WriteLine(str);
sw.Close();
}
}
这里有一个小bug,就是新添加的组件默认是enabled的,所以替换时需要判断animator是否是enabled的,也就是需要把一些基类属性做一个赋值;
Unity中获取Assets下的资源路径的方式
Unity中的资源可分为两类(参考:Unity资源管理机制),一种是需要实例化的资源,也就是prefab,另一种是采用引用计数的资源,如材质,动画、纹理等,
对于prefab,可用如下方式:
PrefabUtility.GetPrefabAssetPathOfNearestInstanceRoot
对于第二种类型资源,可以通过组件拿到引用后,使用如下方式:
AssetDatabase.GetAssetPath()