美文网首页
[Unity Editor]将Animation Clip嵌入A

[Unity Editor]将Animation Clip嵌入A

作者: _Walker__ | 来源:发表于2020-06-11 21:55 被阅读0次

    参考文章:
    Unity中将Animation Clip嵌入Animator Controller的方法

      我要做这个工具的原因,跟参考文章类似,偶然发现项目中有的Clip跟Controller是一个整体,这种方式比较方便管理简单动画,所以搜了下创建方案。
      这里又造轮子,主要是拓展功能与修复参考文章的Bug,代码都在下面,拓展的内容是:

    • 增加删除某个内嵌Clip的功能
    • 修复Bug:参考文章中,Clip内嵌到Controller后,Controller中动画状态Motion并没有跟Clip关联起来
    • 性能小优化:内嵌过程中,没必要重新导入每个Clip,再最后执行一次即可(因为每次重新导入的都是Controller)
    [MenuItem("Assets/Anime/Nest Clips in Controller")]
    public static void NestAnimClips()
    {
        AnimatorController ctrl = Selection.activeObject as AnimatorController;
        if (null == ctrl) return;
    
        AnimationClip[] clips = ctrl.animationClips;
        for (int i = 0; i < clips.Length; ++i)
        {
            AnimationClip clip = clips[i];
            var assetPath = AssetDatabase.GetAssetPath(clip);
            if (assetPath.EndsWith(".anim"))
            {
                AnimationClip newClip = Object.Instantiate(clip);
                newClip.name = clip.name;
                AssetDatabase.AddObjectToAsset(newClip, ctrl);
                AssetDatabase.DeleteAsset(AssetDatabase.GetAssetPath(clip));
                ReplaceStateMotion(ctrl, clip, newClip);
            }
        }
        AssetDatabase.SaveAssets();
    }
    
    [MenuItem("Assets/Anime/Remove Nest Clip")]
    public static void RemoveNestAnimClip()
    {
        AnimationClip clip = Selection.activeObject as AnimationClip;
        if(clip == null) return;
        string ctrlPath = AssetDatabase.GetAssetPath(clip);
        // 保证只移除嵌套的clip,否则会导致动画状态错乱
        if(!ctrlPath.EndsWith(".controller")) return;
    
        AssetDatabase.RemoveObjectFromAsset(clip);
        Object.DestroyImmediate(clip);
        AssetDatabase.SaveAssets();
    }
    
    
    /// <summary>
    /// 替换动画控制器中使用的Clip
    /// </summary>
    public static void ReplaceStateMotion(AnimatorController ctrl, AnimationClip oldClip, AnimationClip newClip, bool replaceAll=false)
    {
        foreach (AnimatorControllerLayer layer in ctrl.layers)
        {
            foreach (ChildAnimatorState childState in layer.stateMachine.states)
            {
                if (childState.state.motion == oldClip)
                {
                    ctrl.SetStateEffectiveMotion(childState.state, newClip);
                    if (!replaceAll) return;
                }
            }
        }
    }
    

    相关文章

      网友评论

          本文标题:[Unity Editor]将Animation Clip嵌入A

          本文链接:https://www.haomeiwen.com/subject/yyiitktx.html