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);
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM