unity 动画状态机重复利用

Posted xiaogeformax

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了unity 动画状态机重复利用相关的知识,希望对你有一定的参考价值。

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;
    

以上是关于unity 动画状态机重复利用的主要内容,如果未能解决你的问题,请参考以下文章

unity状态机怎么调出来

unity 动画状态机控制行走,人物怎么不懂

Unity动画知识之二:Animator动画状态机

unity 有了行为树还用状态机吗

unity-动画状态机Animator

Unity/C#:如何在动画状态机中禁用组件