Animator override Controller

Animator override Controller 是依托于Animator 使用的,应用于相同的动画逻辑,但是根据不同的对象,使用不同的动画clip

创建方法:在project视图中 create->

指定所要绑定的原始animator,并且对应原始animator上的clip指定代替的clip。

运行起来之后,挂载Animator override Controller 则会使用指定的clip替换原有动作。

例如动作可以复用,但是表情不同的情况下则可以使用Animator override Controller,近行区分。

数量较大的时候,最好使用编辑器脚本自动处理。

简单的示例(夹杂了一些当前项目中的设置,没来及全都拆干净)

 

using UnityEngine;
using UnityEditor;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using Object = UnityEngine.Object;

public class AutoOverrideAnimator
{
    //菜单
    [MenuItem("Tools/setAnim")]

    public static void AutoSetAnim()
    {
        //获取选中的目标
        Object[] selection = Selection.GetFiltered(typeof(Object), SelectionMode.DeepAssets);
        Dictionary<string, AnimationClip> commonClips = new Dictionary<string, AnimationClip>();
        Dictionary<string, ModelImporter> commonModels = new Dictionary<string, ModelImporter>();
        //动画路径
        string path = "Assets/GameAssets/Animations/common";
        if (Directory.Exists(path))
        {
            DirectoryInfo direction = new DirectoryInfo(path);
            FileInfo[] files = direction.GetFiles("*", SearchOption.AllDirectories);
            //加载所有的动画clip
            foreach (var file in files)
            {
                AnimationClip clip = AssetDatabase.LoadAssetAtPath(path + "/" + file.Name, typeof(AnimationClip)) as AnimationClip;
                if (clip)
                {
                    if (!commonClips.ContainsKey(clip.name))
                        commonClips.Add(clip.name, clip);
                    else
                    //有重复的clip名时logError
                        Debug.LogError("same key :" + clip.name + ":" + file.Name);
                }
                //加载 ModelImporter 用于确认动画长度等参数。
                var model = ModelImporter.GetAtPath(path + "/" + file.Name) as ModelImporter;
                if (!model) continue;
                if (clip != null && !commonModels.ContainsKey(clip.name))
                {
                    commonModels.Add(clip.name,model);
                }
            }
        }
        
        foreach (var obj in selection)
        {
            if(obj is AnimatorOverrideController)
            {
                //根据明明方式近行 分割
                string key = obj.name.Split(' ')[1];
                Debug.LogError(key);
                path = "Assets/GameAssets/puppy/Animations/" + key;
                string commonPath = "Assets/GameAssets/puppy/Animations/common";
                Dictionary<string, AnimationClip> clips = new Dictionary<string, AnimationClip>();
                AnimatorOverrideController contro = (AnimatorOverrideController)obj;
                AnimationClipOverrides clipOverrides = new AnimationClipOverrides(contro.overridesCount);
                contro.GetOverrides(clipOverrides);
                AnimationClip[] useClips = contro.animationClips;
                List<string> useNames = useClips.Select(useClip => useClip.name).ToList();

                if (Directory.Exists(path))
                {
                    DirectoryInfo direction = new DirectoryInfo(path);
                    FileInfo[] files = direction.GetFiles("*", SearchOption.AllDirectories);
                    foreach(var file in files)
                    {
                        AnimationClip clip = AssetDatabase.LoadAssetAtPath(path + "/" + file.Name, typeof(AnimationClip)) as AnimationClip;
                        if (clip)
                        {
                            if (!useNames.Contains(clip.name))
                            {
                                continue;
                            }
                            if (!clips.ContainsKey(clip.name))
                                clips.Add(clip.name, clip);
                            else
                                Debug.LogError("same key :"+clip.name +":"+ file.Name);

                            var strs = clip.name.Split('_');
                            if (strs[strs.Length - 1] != "h") continue;
                            var bName = clip.name.Substring(0, clip.name.Length - 1) + 'b';
                            if (!commonClips.ContainsKey(bName)) continue;
                            float bLastFrame = 0;
                            float hLastFrame = 0;
                            var model = ModelImporter.GetAtPath(path + "/" + file.Name) as ModelImporter;    
                            if (model != null && model.clipAnimations[0]!=null)
                            {
                                hLastFrame = model.clipAnimations[0].lastFrame;
                            }

                            ModelImporter bmodel = null;
                            if (commonModels.ContainsKey(bName))
                            {
                                bmodel = commonModels[bName];
                                bLastFrame = bmodel.clipAnimations[0].lastFrame;
                            }

                            if (model!=null&&bmodel!=null&&bLastFrame!=0f&&hLastFrame!=0f&&bLastFrame!=hLastFrame)
                            {
                                var bname = bmodel.assetPath.Split('/');
                                var hname = model.assetPath.Split('/');
                                Debug.LogError(key +":"+ clip.name + " animation length dose not Match! " +
                                               bname[bname.Length-1]+"frame:"+bLastFrame+"--"+hname[hname.Length-1]+"frame:"+hLastFrame);
                            }
                        }
                    }
                }
                

                for(int i=0;i< useClips.Length;i++)
                {
                    AnimationClip cp;
                    if (clips.TryGetValue(useClips[i].name,out cp))
                    {
                        clipOverrides[useClips[i].name] = cp;
                    }
                    else if(commonClips.TryGetValue(useClips[i].name, out cp))
                    {
                        clipOverrides[useClips[i].name] = cp;
                    }
                    if (cp == null)
                    {
                        Debug.LogError("Can not found "+ key + ":"+ useClips[i].name);
                    }
                    
                }
                contro.ApplyOverrides(clipOverrides);
            }
        }
        AssetDatabase.SaveAssets();
    }
    public class AnimationClipOverrides : List<KeyValuePair<AnimationClip, AnimationClip>>
    {
        public AnimationClipOverrides(int capacity) : base(capacity) { }

        public AnimationClip this[string name]
        {
            get { return this.Find(x => x.Key.name.Equals(name)).Value; }
            set
            {
                int index = this.FindIndex(x => x.Key.name.Equals(name));
                if (index != -1)
                    this[index] = new KeyValuePair<AnimationClip, AnimationClip>(this[index].Key, value);
            }
        }
    }
}

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值