using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEditor; using UnityEditor.Animations;
public class AnimatorCreater {
[MenuItem("Assets/制作动画控制器", false, 0)]
public static void Create()
{
string[] guids = Selection.assetGUIDs;//获取当前选中的asset的GUID
for (int i = 0; i < guids.Length; i++)
{
string assetPath = AssetDatabase.GUIDToAssetPath(guids[i]);//通过GUID获取路径
AnimatorController Ctrl = AssetDatabase.LoadAssetAtPath<AnimatorController>(assetPath);
if (Ctrl != null)
{
List<AnimationClip> acs = new List<AnimationClip>();
Object[] objects = AssetDatabase.LoadAllAssetRepresentationsAtPath(assetPath);
foreach (Object obj in objects)
{
AnimationClip clip = obj as AnimationClip;
if (clip != null)
{
acs.Add(clip);
}
}
BuildController(Ctrl, acs);
}
}
}
private static void BuildController(AnimatorController Ctrl, List<AnimationClip> acs)
{
//分析所有的动画
List<AnimatorStateInfo> animatorStateInfos = new List<AnimatorStateInfo>();
Dictionary<string, AnimatorState> stateDic = new Dictionary<string, AnimatorState>();
AnimatorControllerLayer layer = Ctrl.layers[0];
AnimatorStateMachine sm = layer.stateMachine;
ClearStateMachine(sm);
ClearAnimatorControllerParameter(Ctrl);
sm.anyStatePosition = Vector3.zero;
sm.entryPosition = new Vector3(0, 200, 0);
sm.exitPosition = new Vector3(0, 400, 0);
//处理动画
foreach (var item in acs)
{
animatorStateInfos.Add(BuildAnimatorStateInfo(item, acs));
}
//生成状态
for (int i = 0; i < animatorStateInfos.Count; i++)
{
animatorStateInfos[i].state = sm.AddState(animatorStateInfos[i].ac.name, animatorStateInfos[i].pos);
animatorStateInfos[i].state.motion = animatorStateInfos[i].ac;
stateDic.Add(animatorStateInfos[i].ac.name, animatorStateInfos[i].state);
}
//生成连线
foreach (var item in animatorStateInfos)
{
AnimatorStateTransition enterTrans = null;
AnimatorStateTransition outTrans = null;
//进入连线
if (item.Enter == "Any")
{
enterTrans = sm.AddAnyStateTransition(item.state);
}
else
{
enterTrans = stateDic[item.Enter].AddTransition(item.state);
}
enterTrans.hasExitTime = false;
enterTrans.duration = 0.98f;
//进入条件
if (!string.IsNullOrEmpty(item.condiation))
{
Ctrl.AddParameter(item.condiation, AnimatorControllerParameterType.Trigger);
enterTrans.AddCondition(AnimatorConditionMode.If, 0, item.condiation);
}
if (!string.IsNullOrEmpty(item.Out))
{
outTrans = item.state.AddTransition(stateDic[item.Out]);
enterTrans.hasExitTime = false;
enterTrans.duration = 0.98f;
}
}
//处理默认
}
public static void ClearAnimatorControllerParameter(AnimatorController Ctrl)
{
Ctrl.parameters = null;
}
public static void ClearStateMachine(AnimatorStateMachine sm)
{
ChildAnimatorState[] cass = sm.states;
foreach (var item in cass)
{
sm.RemoveState(item.state);
}
}
private static int lineH = 100;
private static int lineW = 250;
public static AnimatorStateInfo BuildAnimatorStateInfo(AnimationClip clip, List<AnimationClip> AllClipName)
{
AnimatorStateInfo asi = new AnimatorStateInfo(clip);
if (clip.name.Contains("Awake"))
{
asi.Enter = "Any";
asi.condiation = "EnterState_" + asi.stateID;
asi.pos = new Vector3(0 * lineW, asi.stateID * lineH, 0);
}
if (clip.name.Contains("Wait"))
{
string checkEnter = asi.stateID + "_Awake";
if (AllClipName.Find(x => x.name == checkEnter))
{
asi.Enter = checkEnter;
}
else
{
asi.Enter = "Any";
asi.condiation = "EnterState_" + asi.stateID;
}
asi.pos = new Vector3(lineW * 1, asi.stateID * lineH, 0);
AnimationClipSettings clipSetting = AnimationUtility.GetAnimationClipSettings(clip);
clipSetting.loopTime = !clip.isLooping;
AnimationUtility.SetAnimationClipSettings(clip, clipSetting);
}
if (clip.name.ToLower().Contains("atk"))
{
//蓄力的
if (asi.Splits.Length > 2)
{
if (asi.Splits[2] == "P")
{
asi.Enter = asi.stateID + "_Wait";
asi.condiation = clip.name;
asi.pos = new Vector3(lineW * 2, asi.stateID * lineH, 0);
}
else if (asi.Splits[2] == "C")
{
asi.Enter = asi.Splits[0] + "_" + asi.Splits[1] + "_P";
asi.pos = new Vector3(lineW * 3, asi.stateID * lineH, 0);
AnimationClipSettings clipSetting = AnimationUtility.GetAnimationClipSettings(clip);
clipSetting.loopTime = !clip.isLooping;
AnimationUtility.SetAnimationClipSettings(clip, clipSetting);
}
else if (asi.Splits[2] == "R")
{
asi.Enter = asi.Splits[0] + "_" + asi.Splits[1] + "_C";
asi.Out = asi.stateID + "_Wait";
asi.condiation = clip.name;
asi.pos = new Vector3(lineW * 4, asi.stateID * lineH, 0);
}
}
else
{
asi.pos = new Vector3(lineW * 2, asi.stateID * lineH, 0);
asi.Enter = asi.stateID + "_Wait";
asi.condiation = clip.name;
asi.Out = asi.stateID + "_Wait";
}
}
return asi;
}
}
public class AnimatorStateInfo { public AnimationClip ac; public AnimatorState state;
public string Enter;
public string Out;
public string condiation;
public int stateID;
public Vector3 pos;
public string[] Splits;
public AnimatorStateInfo(AnimationClip ac)
{
this.ac = ac;
Splits = ac.name.Split('_');
stateID = int.Parse(Splits[0]);
}
}
|