美文网首页
unity3d自动生成动画状态机

unity3d自动生成动画状态机

作者: Jokerfang | 来源:发表于2016-08-06 16:53 被阅读0次

    因项目需要,人物30多个,每个人物动画以及命名都是一样。新版的动画系统Mecanim,支持连线之类,想在新项目中使用。但是让策划一个个手动去连线,设置触发条件太麻烦了也容易出错。(初步我们有4个动作 "walk", "idle", "attack", "skill",四个动作可以直接相互切换)

    网上没找到类似的代码。。于是写了个简单的插件来处理。直接上代码。。这个就自动连线和设置里面的条件了。
    先搜索整个目录下的fbx文件(动作和模型做到一起去了),然后根据制定的几个动作,自动生成状态机,包括设置好触发条件。

    Paste_Image.png

    自动生成的生成的动画状态机

    using UnityEngine;
    using System.Collections;
    using UnityEditor;
    using System.IO;
    using System.Collections.Generic;
    
    
    public class AutoAnimatorCtl : Editor
    {
        [MenuItem("test/AutoAnimatorCtl")]
        static void batchAnimatorCtl()
        {
            string dirPath = "Assets/Media/Character/Model/";
            foreach (string path in Directory.GetFiles(dirPath))
            {
                if (System.IO.Path.GetExtension(path) == ".FBX")
                {
                        createAnimatorCtl(path);
                }
            }
        }
        static bool isUniqueState(string str)
        {
            string[] states = { "walk", "idle", "attack", "skill" };
            foreach (string state in states)
            {
                if (str == state)
                    return true;
            }
            return false;
        }
        //检查fbx里面动画的完整性
        static bool checkFullAnimation(Object[] objs)
        {
            string[] clipName = { "walk", "idle", "attack", "skill" };
            //Object[] objs = AssetDatabase.LoadAllAssetsAtPath(path);
            int num = 0;
            foreach (Object obj in objs)
            {
                if(obj is AnimationClip && isUniqueState(obj.name))
                {
                    num = num + 1;
                }
            }
            if (num == clipName.Length)
                return true;
            return false;
        }
        static void createAnimatorCtl(string path)
        {
            path = path.Replace("\\", "/");
            path = path.Replace(".FBX", ".fbx");
            string acPath = path.Replace(".fbx", ".controller");
            string prePath = path.Replace(".fbx", ".prefab");
            Object[] objs = AssetDatabase.LoadAllAssetsAtPath(path);
            var animatorController = UnityEditor.Animations.AnimatorController.CreateAnimatorControllerAtPath(acPath);
            var layer = animatorController.layers[0];
            var anmationStateMachine = layer.stateMachine;
            List<UnityEditor.Animations.AnimatorState> states = new List<UnityEditor.Animations.AnimatorState>();
            foreach (Object obj in objs)
            {
                if (obj is AnimationClip && isUniqueState(obj.name) == true)
                {
                    Debug.Log(obj.name + " is clip");
                    var state = anmationStateMachine.AddState(obj.name);
                    states.Add(state);
                    state.motion = obj as Motion;
                }
            }
            animatorController.AddParameter("walk", AnimatorControllerParameterType.Bool);
            animatorController.AddParameter("skill", AnimatorControllerParameterType.Bool);
            animatorController.AddParameter("attack", AnimatorControllerParameterType.Bool);
            animatorController.AddParameter("idle", AnimatorControllerParameterType.Bool);
            
            for(int i = 0; i< states.Count;i++)
            {
                for(int j = 0; j < states.Count; j++)
                {
                    if(i != j)
                    {
                        var anstateTras = states[i].AddTransition(states[j], false);
                        anstateTras.AddCondition(UnityEditor.Animations.AnimatorConditionMode.If, 0, states[j].name);
                    }
                }
                if(states[i].name == "idle")
                {
                    anmationStateMachine.defaultState = states[i];
                }
            }
        }
    }
    

    相关文章

      网友评论

          本文标题:unity3d自动生成动画状态机

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