欢迎光临散文网 会员登陆 & 注册

【Unity技巧4】使用代码给动画状态机批量连线

2022-08-21 17:40 作者:机智的小草yns  | 我要投稿

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

那么如何优雅得连线呢?

那就是使用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}");
                EditorUtility.SetDirty(ac);
                return true;
            }
            else
            {
                Debug.Log($"yns has {item.name}");
                return false;
            }
        }

        [MenuItem("Assets/AnimatorTool/移除所有连线")]
        public static void RemoveAllTransmiss()
        {
            OnRemoveAllTransmiss(Selection.activeObject as AnimatorController);
        }


        [MenuItem("Assets/AnimatorTool/自动连线")]
        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")
                {
                    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 " + item.destinationState);
                stateMachine.RemoveEntryTransition(item);
            }
            foreach (var item in stateMachine.anyStateTransitions)
            {
                Debug.Log("yns  remove " + item.destinationState);
                stateMachine.RemoveAnyStateTransition(item);
            }

            //foreach (var item in ac.layers[0].stateMachine.stateMachines)
            //{
            //    //Debug.Log("yns  stateMachines " + 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 " + item.state.ToString());
                foreach (var tr in item.state.transitions)
                {
                    item.state.RemoveTransition(tr);
                }
            }
            EditorUtility.SetDirty(ac);
            AssetDatabase.SaveAssets();
        }
    }



【Unity技巧4】使用代码给动画状态机批量连线的评论 (共 条)

分享到微博请遵守国家法律