先上图
上图为一个简单的怪物状态机,是通过代码自动生成连线的,但是里面的动画需要自己设置
那么如何做到
官方参考:https://docs.unity3d.com/ScriptReference/Animations.AnimatorController.html
民间参考:https://www.jianshu.com/p/cf1b54b78c23
我的代码:
using System; using System.Collections; using System.Collections.Generic; using Framework; using UnityEditor; using UnityEditor.Animations; using UnityEngine; /// <summary> /// 状态机自动连线 /// 使用方法:选择Project视图里面的动画状态机文件,右键——>创建怪物动画状态机 /// </summary> public class EditorAnimator { [MenuItem("Assets/创建怪物动画状态机", priority = 0)] static void CreateUIView() { AnimatorController ac = (AnimatorController)Selection.objects[0]; AnimatorStateMachine stateMachine = ac.layers [0].stateMachine; //添加动画容器 AddNewState(stateMachine, "Die", new Vector3(300, 20, 0)); AddNewState(stateMachine, "Idle", new Vector3(300, 120, 0)); AddNewState(stateMachine, "Run", new Vector3(300, 220, 0)); AddNewState(stateMachine, "Attack", new Vector3(600, 220, 0)); #region 添加状态 AddBoolBehaviour(stateMachine, "Idle", "IsIdle",true, SetParameter.Parameter.SetWhen.OnEnter); AddBoolBehaviour(stateMachine, "Idle", "IsIdle",false, SetParameter.Parameter.SetWhen.OnExit); AddBoolBehaviour(stateMachine, "Die", "IsDie",true, SetParameter.Parameter.SetWhen.OnEnter); AddBoolBehaviour(stateMachine, "Die", "IsDie",false, SetParameter.Parameter.SetWhen.OnExit); AddBoolBehaviour(stateMachine, "Run", "IsRun",true, SetParameter.Parameter.SetWhen.OnEnter); AddBoolBehaviour(stateMachine, "Run", "IsRun",false, SetParameter.Parameter.SetWhen.OnExit); AddBoolBehaviour(stateMachine, "Attack", "IsAttack",true, SetParameter.Parameter.SetWhen.OnEnter); AddBoolBehaviour(stateMachine, "Attack", "IsAttack",false, SetParameter.Parameter.SetWhen.OnExit); #endregion //连线,并且添加条件 var line = StateLine(stateMachine, "Idle", "Run"); line.AddCondition(AnimatorConditionMode.Greater, 0.01f, "speed");//数值大小式 var line2 = StateLine(stateMachine, "Run", "Idle"); line2.AddCondition(AnimatorConditionMode.Less, 0.01f, "speed");//数值大小式 var line3 = StateLine(stateMachine, "Run", "Attack"); line3.AddCondition(AnimatorConditionMode.If, 0, "attack");//Trigger触发式 var line4 = StateLine(stateMachine, "Idle", "Attack"); line4.AddCondition(AnimatorConditionMode.If, 0, "attack");//Trigger触发式 StateLine(stateMachine, "Attack", "Idle", true); var line5 = StateLine(stateMachine, "Die", "Idle"); line5.AddCondition(AnimatorConditionMode.IfNot, 0, "die");//bool-false //任意状态到死亡 var lineDie = stateMachine.AddAnyStateTransition(GetStateByName(stateMachine, "Die")); lineDie.AddCondition(AnimatorConditionMode.If, 0, "die");//bool-true lineDie.AddCondition(AnimatorConditionMode.IfNot, 0, "IsDie");//bool-false } static void AddNewState(AnimatorStateMachine stateMachine, string name, Vector3 v3) { bool has = false; foreach (var one in stateMachine.states) { //Debug.Log(one.state.name); if (one.state.name.Equals(name)) { has = true; } } if (!has) { stateMachine.AddState(name, v3); } } static AnimatorState GetStateByName(AnimatorStateMachine stateMachine, string name) { foreach (var one in stateMachine.states) { if (one.state.name.Equals(name)) { return one.state; } } return null; } //连线 static AnimatorStateTransition StateLine(AnimatorStateMachine stateMachine, string name1, string name2,bool defaultExitTime = false) { return GetStateByName(stateMachine, name1).AddTransition(GetStateByName(stateMachine, name2), defaultExitTime); } //添加StateMachineBehaviour,并且设置 static void AddBoolBehaviour(AnimatorStateMachine stateMachine, string name,string paraName, bool v, SetParameter.Parameter.SetWhen when) { SetParameter.Parameter parameter = new SetParameter.Parameter(); parameter.Name = paraName; parameter.Type = AnimatorControllerParameterType.Bool; parameter.BoolValue = v; parameter.When = when; SetParameter para; if (GetStateByName(stateMachine, name).behaviours.Length == 0) { para = GetStateByName(stateMachine, name).AddStateMachineBehaviour<SetParameter>(); } else { para = (SetParameter)GetStateByName(stateMachine, name).behaviours[0]; } if (para.Parameters == null) { para.Parameters = new List<SetParameter.Parameter>(); } para.Parameters.Add(parameter); EditorUtility.SetDirty(para); } }