因项目需要,人物30多个,每个人物动画以及命名都是一样。新版的动画系统Mecanim,支持连线之类,想在新项目中使用。但是让策划一个个手动去连线,设置触发条件太麻烦了也容易出错。(初步我们有4个动作 "walk", "idle", "attack", "skill",四个动作可以直接相互切换)
网上没找到类似的代码。。于是写了个简单的插件来处理。直接上代码。。这个就自动连线和设置里面的条件了。
先搜索整个目录下的fbx文件(动作和模型做到一起去了),然后根据制定的几个动作,自动生成状态机,包括设置好触发条件。
自动生成的生成的动画状态机
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];
}
}
}
}