Unity中将Animation Clip嵌入Animator Controller的方法

最近再研究Unity的UI动效果,过程中发现一个小细节:在使用UGUI的Button时,如果设置Transition过渡方式为Animation动画,并通过Auto Generate Animation自动生成Animator Controller及四个按钮状态对应的Animation时,会发现生成的Asset资源是这样

和其他FBX动画等一样,动画Animation Clip是直接嵌入Controller的,而当实现一些如UI弹出动画之类的效果时,也使用Animator,自己手动创建Controller后,却没有可视化的直接在创建内嵌Clip以及State的方法,只能创建State然后关联Clip,或者先创建Clip,再拖入Controller自动生成关联State,最后Asset里会是这样:

看着明显不如Button自动生成的那种要整洁!

后来在Unity论坛上发现了一篇讨论这个问题的帖子:https://forum.unity.com/threads/embedding-motion-clips-in-the-controller-asset.379885/,其中提供了一个Editor脚本实现了此功能,我测试了一下发现有个小bug(不能在已有内嵌Clip的Controller中嵌入新的Clip),简单修正了下:

//  ==================================================================================================================
//  <description>NestAnimClips.cs - Nesting AnimationClips inside an AnimationContoller.</description>
//  <author>ZombieGorilla for Unity Forums, Modified by K-Res.</author>
//  <version>1.0</version>
//  <date>2016-02-14</date>
//  ==================================================================================================================

using UnityEngine;
using UnityEditor;

public class NestAnimClips : MonoBehaviour
{
    [MenuItem("Assets/Nest AnimClips in Controller")]
    static public void nestAnimClips()
    {
        UnityEditor.Animations.AnimatorController anim_controller = null;
        AnimationClip[] clips = null;

        if (Selection.activeObject.GetType() == typeof(UnityEditor.Animations.AnimatorController))
        {
            anim_controller = (UnityEditor.Animations.AnimatorController)Selection.activeObject;
            clips = anim_controller.animationClips;

            if (anim_controller != null && clips.Length > 0)
            {
                foreach (AnimationClip ac in clips)
                {
                    var acAssetPath = AssetDatabase.GetAssetPath(ac);
                    // Check if this ac is not in the controller
                    if (acAssetPath.EndsWith(".anim"))
                    {
                        var new_ac = Object.Instantiate(ac) as AnimationClip;
                        new_ac.name = ac.name;

                        AssetDatabase.AddObjectToAsset(new_ac, anim_controller);
                        AssetDatabase.ImportAsset(AssetDatabase.GetAssetPath(new_ac));
                        AssetDatabase.DeleteAsset(AssetDatabase.GetAssetPath(ac));
                    }
                }
                Debug.Log("<color=orange>Added " + clips.Length.ToString() + " clips to controller: </color><color=yellow>" + anim_controller.name + "</color>");
            }
            else
            {
                Debug.Log("<color=red>Nothing done. Select a controller that has anim clips to nest.</color>");
            }
        }

    }
}

使用方法很简单,选中Animator Controller资源,然后右键菜单中选”Nest AnimClips in Controller”,即可将此Controller中所有外部Clip都嵌入进来。
PS:暂时没实现反向操作,且执行过后会删除外部Clip资源,因此,友情提示:重要Clip资源先备份,或者注释掉DeleteAsset那句!

博主友情提示:

如您在评论中需要提及如QQ号、电子邮件地址或其他隐私敏感信息,欢迎使用>>博主专用加密工具v3<<处理后发布,原文只有博主可以看到。