unity3d自动生成动画状态机

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

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

unity3d自动生成动画状态机_第1张图片
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 states = new List();
        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自动生成动画状态机)