先上图
上图为一个简单的怪物状态机,是通过代码自动生成连线的,但是里面的动画需要自己设置
那么如何做到
官方参考: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;
///
/// 状态机自动连线
/// 使用方法:选择Project视图里面的动画状态机文件,右键——>创建怪物动画状态机
///
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
}
else
{
para = (SetParameter)GetStateByName(stateMachine, name).behaviours[0];
}
if (para.Parameters == null)
{
para.Parameters = new List
}
para.Parameters.Add(parameter);
EditorUtility.SetDirty(para);
}
}
好文链接
发表评论