先上圖
上圖為一個簡單的怪物狀態機,是通過代碼自動生成連線的,但是里面的動畫需要自己設置
那么如何做到
官方參考: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); } }