【Unity技巧4】使用代码给动画状态机批量连线
机智的小草yns
2022年08月21日 17:40
收录于文集
共30篇

前段时间写技能编辑器的时候, 发现很多的动画片段需要连线,手动连线肯定是很麻烦。

那么如何优雅得连线呢?

那就是使用AnimatorStateMachine的API来完成这些事件。

核心API AnimatorStateMachine.AddTransition //连线 AnimatorStateMachine.AddExitTransition  //连线到退出 AnimatorStateMachine.RemoveEntryTransition //移除连线 AnimatorState.AddState //添加动画片段到状态机

使用示例

编辑器代码:     public static class XiaocaoEditorAnimTool     {         //添加一个Clip到动画机         public static bool AddClipToAnimator(AnimatorController ac, AnimationClip item)         {             if (!ac.animationClips.Contains(item))             {                 AnimatorStateMachine sm = ac.layers[0].stateMachine;                 AnimatorState state = sm.AddState(item.name, sm.exitPosition + Vector3.up * Random.Range(100, 800));                 state.motion = item;                 state.AddExitTransition(true);                 Debug.Log($"anim add {item.name}&#​34;);                 EditorUtility.SetDirty(ac);                 return true;             }             else             {                 Debug.Log($"yns has {item.name}&#​34;);                 return false;             }         }         [MenuItem("Assets/AnimatorTool/移除所有连线&#​34;)]         public static void RemoveAllTransmiss()         {             OnRemoveAllTransmiss(Selection.activeObject as AnimatorController);         }         [MenuItem("Assets/AnimatorTool/自动连线&#​34;)]         public static void SetIdleTransmiss()         {             RemoveAllTransmiss();             OnSetIdleTransmiss(Selection.activeObject as AnimatorController);         }         public static void OnSetIdleTransmiss(AnimatorController ac)         {             foreach (var item in ac.layers[0].stateMachine.states)             {                 if (item.state.name.ToLower() != "idle&#​34;)                 {                     item.state.AddExitTransition(true);                 }             }         }         public static void OnRemoveAllTransmiss(AnimatorController ac, List<string> unRemoves = null)         {             var stateMachine = ac.layers[0].stateMachine;             foreach (var item in stateMachine.entryTransitions)             {                 if (unRemoves != null)                 {                     if (unRemoves.Contains(item.destinationState.name))                     {                         continue;                     }                 }                 Debug.Log("yns  remove &#​34; + item.destinationState);                 stateMachine.RemoveEntryTransition(item);             }             foreach (var item in stateMachine.anyStateTransitions)             {                 Debug.Log("yns  remove &#​34; + item.destinationState);                 stateMachine.RemoveAnyStateTransition(item);             }             //foreach (var item in ac.layers[0].stateMachine.stateMachines)             //{             //    //Debug.Log("yns  stateMachines &#​34; + item.stateMachine.ToString());             //}             foreach (var item in ac.layers[0].stateMachine.states)             {                 if (unRemoves != null)                 {                     if (unRemoves.Contains(item.state.name))                     {                         continue;                     }                 }                 Debug.Log("yns  states &#​34; + item.state.ToString());                 foreach (var tr in item.state.transitions)                 {                     item.state.RemoveTransition(tr);                 }             }             EditorUtility.SetDirty(ac);             AssetDatabase.SaveAssets();         }     }