Unity Animator自动连线

先上图

 

 上图为一个简单的怪物状态机,是通过代码自动生成连线的,但是里面的动画需要自己设置

那么如何做到

官方参考: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);
    }
}

 

posted @ 2020-04-03 10:08  三页菌  阅读(1442)  评论(0编辑  收藏  举报