unity 动画状态机重复利用

12 篇文章 0 订阅
4 篇文章 0 订阅

unity 动画状态机重复利用

在unity 项目工程里,常有几十个NPC,几十个小怪的动画状态机都是相同的,类似于这个情况,可以只需要制作一套状态机,复制到每个动画的文件夹里面,然后就是拉入动画了。这里写图片描述
这里写图片描述
这个的前提就是每个动画里面都是相同的,大家的状态机都是一样的。
下面的工具就是方便来导入动画的,是相应的动画状态机保持着相应的动画。

代码和介绍

[MenuItem("Assets/替换为当前文件夹的动画")]
    public static void ReplaceAnimatorClips()
    {
        Object animObj = Selection.activeObject;
        AnimatorController animator = animObj as AnimatorController;

        string folderpath = Path.GetDirectoryName(AssetDatabase.GetAssetPath(animObj));
        GetAllFiles(folderpath);

        if (files.Count <= 0) return;

        animationClips.Clear();
        for (int i = 0; i < files.Count; i++)
        {
            string name = Path.GetFileNameWithoutExtension(files[i]);
            string[] names = name.Split('@');
            if (names.Length == 2)
            {
                string clipname = names[1];
                animationClips[clipname.ToLower()] = files[i];
            }
        }

        ChildAnimatorState[] childstates = animator.layers[0].stateMachine.states;
        foreach (var childstate in childstates)
        {
            AnimatorState state = childstate.state;
            Motion mo = state.motion;
            if (mo == null)
            {
                Debug.LogError(state.name + "节点动作是空");
                continue;
            }
            if (mo.GetType().Equals(typeof(BlendTree)))
            {
                BlendTree tree = (BlendTree)mo;
                ReplaceMotionInLocalFolder(tree);
            }
            else
            {
                ReplaceMotionInLocalFolder(state);
            }
        }
        AssetDatabase.SaveAssets();
    }

[MenuItem(“Assets/替换为当前文件夹的动画”)]
这句代码我们选中所需要的状态机就可以鼠标右键来快捷方式调用这个方法了。

在判断动画状态机里面不为空的时候,就可以去改变里面的动画片段了。
在这里我们分为两种,一种是普通动画,一种是BlendTree。

 if (mo.GetType().Equals(typeof(BlendTree)))
            {
                BlendTree tree = (BlendTree)mo;
                //取代BlendTree里面的动画
                ReplaceMotionInLocalFolder(tree);
            }
            else
            {
	            //取代普通的动画
                ReplaceMotionInLocalFolder(state);
            }

普通的动画

 public static void ReplaceMotionInLocalFolder(AnimatorState state)
    {
        string name = state.motion.name;
        if (GetLocalMotionFile(name) != null)
        {
            state.motion = GetLocalMotionFile(name);
        }
    }

这里是更换普通的动画片段,只需要把普通的名字传进去,更换一下就是可以的了。
同时看下 GetLocalMotionFile 函数

//animationClips 为动画片段
    static Dictionary<string, string> animationClips = new Dictionary<string, string>();
    public static Motion GetLocalMotionFile(string name)
    {
        if (animationClips.ContainsKey(name.ToLower()))
        {
            AnimationClip mo = AssetDatabase.LoadAssetAtPath(animationClips[name.ToLower()], typeof(AnimationClip)) as AnimationClip;
            if (mo != null)
            {
                return mo;
            }
            else
            {
                Debug.LogWarning("no this name clip in this folder" + name);
            }
        }
        else
        {
            Debug.LogWarning("no this name clip in this folder" + name);
        }
        return null;
    }
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值