Unity工具 将预制体内的animator组件替换成animation

如下是一个自动将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()

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值