unityEditor下自动生成AnimatorController状态机
Editor下自动生成AnimatorController状态机,并设置animator属性
创建预制体到指定路径
public class CreateAnimatorController: Editor
{
private static string AnimatorPath = @"Assets/Animation/AnimatorCol";
private static string StudentAiPrefabPath = @"Assets/A_Prefabs/Ai/Student";
[MenuItem("Assets/生成状态机", false, 100)]
public static void DisposeStudentModel()
{
Object[] selecTransform = Selection.objects;
if (!Directory.Exists(StudentAiPrefabPath))
{
Directory.CreateDirectory(StudentAiPrefabPath);
}
foreach (var Obj in selecTransform)
{
GameObject tempObj = Instantiate(Obj as GameObject);
//创建预制体到指定路径
GameObject studentPrefab = PrefabUtility.SaveAsPrefabAsset(tempObj, StudentAiPrefabPath + $"/{student.name}.prefab");
DestroyImmediate(tempObj);
}
}
}
创建状态机之前先设置FBX中Animator属性
//设置动画属性以及事件
static void SetAnimationEvent(Object animator)
{
//EditorUtility.SetDirty(animator);
string fbxPath = AssetDatabase.GetAssetPath(animator);
ModelImporter model = AssetImporter.GetAtPath(fbxPath) as ModelImporter;
//必须改为通用或人形 否则不能赋值
model.animationType = ModelImporterAnimationType.Generic;
//更改Clip属性必须要重新建一个Clip
ModelImporterClipAnimation[] tempClipArr = new ModelImporterClipAnimation[model.clipAnimations.Length];
// 更改它的动画模式
for (int i = 0; i < tempClipArr.Length; i++)
{
//把老的Clip赋值给新的Clip
tempClipArr[i] = model.defaultClipAnimations[0];
tempClipArr[i].name = model.clipAnimations[i].name;
tempClipArr[i].firstFrame = model.clipAnimations[i].firstFrame;
tempClipArr[i].lastFrame = model.clipAnimations[i].lastFrame;
//设置新的属性
if (tempClipArr[i].name == "idle" )
{
tempClipArr[i].loopTime = true; //设置循环
}
else
{
tempClipArr[i].loopTime = false;
}
}
//把新的Clip Arr 替换给旧的Clip
model.clipAnimations = tempClipArr;
//保存设置
model.SaveAndReimport();
}
生成状态机到指定位置 将上面的Obg传进来
//创建状态机
public static AnimatorController CreateStudentAnimator(Object Obj)
{
GameObject item_obj = (Obj as GameObject);
item_obj.AddComponent<Animator>();
if (!Directory.Exists(AnimatorPath))
{
Directory.CreateDirectory(AnimatorPath);
}
AnimatorController controller = AnimatorController.CreateAnimatorControllerAtPath(AnimatorPath + $"/{item_obj.name}.controller");
return controller;
}
//给状态机 设置动画
public static void SetClip(Object item, AnimatorController controller)
{
List<AnimationClip> clipList = new List<AnimationClip>();
string fbxPath = AssetDatabase.GetAssetPath(item);
clipList = GetAnimaClip(fbxPath);
AnimationClip idle, s_idle, death, attack;
idle = s_idle = death = attack = null;
foreach (var clip in clipList)
{
switch (clip.name)
{
case "idle": idle = clip; continue;
case "s_idle": s_idle = clip; continue;
case "death": death = clip; continue;
case "attack": attack = clip; continue;
}
}
controller.AddParameter("sidle", AnimatorControllerParameterType.Trigger);
controller.AddParameter("attack", AnimatorControllerParameterType.Trigger);
controller.AddParameter("death", AnimatorControllerParameterType.Trigger);
var rootStateMachine = controller.layers[0].stateMachine;
var stateMachine_idle = rootStateMachine.AddState("idle");
var stateMachineA_idle_s = rootStateMachine.AddState("s_idle");
var stateMachineA_attack = rootStateMachine.AddState("attack");
var stateMachineA_death = rootStateMachine.AddState("death");
stateMachine_idle.motion = idle;
stateMachineA_idle_s.motion = s_idle;
stateMachineA_attack.motion = attack;
stateMachineA_death.motion = death;
//添加Tragger线
var idle_sidle = stateMachine_idle.AddTransition(stateMachineA_idle_s);
idle_sidle.AddCondition(AnimatorConditionMode.If, 0, "sidle");
var idle_attack = stateMachine_idle.AddTransition(stateMachineA_attack);
idle_attack.AddCondition(AnimatorConditionMode.If, 0, "attack");
var attack_idle = stateMachineA_attack.AddTransition(stateMachine_idle);
var sidle_idle = stateMachineA_idle_s.AddTransition(stateMachine_idle);
attack_idle.hasExitTime = true; //播完之后自动回到idle状态
sidle_idle.hasExitTime = true;
//从AnyState到death动画
var toDeath = rootStateMachine.AddAnyStateTransition(stateMachineA_death);
toDeath.AddCondition(AnimatorConditionMode.If, 0, "death");
}
static List<AnimationClip> GetAnimaClip(string fbxPath)
{
Object[] objs = AssetDatabase.LoadAllAssetsAtPath(fbxPath);
List<AnimationClip> srcClipList = new List<AnimationClip>();
foreach (Object o in objs)
{
if (o.GetType() == typeof(AnimationClip))
{
srcClipList.Add(o as AnimationClip);
}
}
return srcClipList;
}