根据Spine动画自动创建代码状态机

Spine创建状态机的方法

导入Spine的三个文件,然后会生成SkeletonData.asset文件,然后将SkeletonData.asset文件拖动到Hierarchy下,选择SkeletonMecanim,能够看到在文件同一目录下生成了controller文件
在这里插入图片描述

代码生成状态机状态和连线

在RPG游戏中,角色有几十个,二他们的动画是类似的,所以应该代码创建生成状态和连线.
我的思路如下:
1.选中动画控制器,它是AnimatorController类型的.
2.创建需要的动画状态,这里我定义了一个枚举:

  public enum AnimatorName
    {
        standby,
        walk,
        attack,
        attack_1,
        death
    }

然后把这些状态添加到动画控制器里面.
3.给这些状态设置相应的动画,设置是否循环,速度等参数.我的Spine动画有这些.这里之前一直找不到得到这些动画的集合的方法,后面终于找到AssetDatabase.LoadAllAssetsAtPath这个API得到.
在这里插入图片描述
4.连线,各个状态都可以切换,我只定义了一个切换条件,当State为对应的枚举值时,切换到对应的状态.

详细代码提供如下:

  [MenuItem("CreateAnimator/CreateDynamicAnimator")]
    public static void CreateDynamicAnimator()
    {
        //选中动画控制器
        Object animObj = Selection.activeObject;
        AnimatorController dynamicAni = animObj as AnimatorController;
        //得到动画控制器第一层的默认动画状态机
        AnimatorStateMachine stateMachine = dynamicAni.layers[0].stateMachine;
        //先移除一下旧的状态
        foreach (var childAnimatorState in stateMachine.states)
        {
            stateMachine.RemoveState(childAnimatorState.state);
        }
        //创建状态集合
        List<AnimatorState> states = new List<AnimatorState>();
        //循环枚举将各个值添加为一个状态
        foreach (int code in Enum.GetValues(typeof(AnimatorName)))
        {
            string strName = Enum.GetName(typeof(AnimatorName), code);
            AnimatorState state = stateMachine.AddState(strName);
            state.speed = 1f;
            states.Add(state);
        }
        //指定默认状态
        stateMachine.defaultState = states[0];
      
        加载动画片段
        string path = AssetDatabase.GetAssetPath(animObj);
        Object[] anis = AssetDatabase.LoadAllAssetsAtPath(path);
        Dictionary<string,AnimationClip> dict =new Dictionary<string, AnimationClip>();
        foreach (var ani in anis)
        {
            if (ani is AnimationClip)
            {
                AnimationClip clim = (AnimationClip) ani;
                dict.Add(clim.name,clim);
                //设置动画循环 除了死亡动作
                if (!ani.name.Equals(AnimatorName.death.ToString()))
                {
                    AnimationClipSettings clipSetting = AnimationUtility.GetAnimationClipSettings(clim);
                    clipSetting.loopTime = true;
                    AnimationUtility.SetAnimationClipSettings(clim, clipSetting);
                }
            }
        }
        //为每一个状态指定相应的动画片段 动画的名字和状态的名字相同
        for (int i = 0; i < states.Count; i++)
        {
            if (!dict.ContainsKey(states[i].name))
            {
                Debug.LogError($"non-existent {states[i].name} AnimationClip");
                return;
            }
            states[i].motion = dict[states[i].name];
            //关闭逆向运动学
            states[i].iKOnFeet = false;
        }
    
        //为动画控制器添加参数,形成参数列表
        dynamicAni.AddParameter("State", AnimatorControllerParameterType.Int);
        //允许任意状态过度到任意状态
        for (int i = 0; i < states.Count; i++)
        {
            for (int j = 0; j < states.Count; j++)
            {
                if (states[i] != states[j])
                {
                    //生成状态之间的触发器,即:连线 
                    AnimatorStateTransition trans = states[i].AddTransition(states[j], false);
                    AnimatorName  temp=(AnimatorName) Enum.Parse(typeof(AnimatorName), states[j].name);
                    //为触发器添加触发条件
                    trans.AddCondition(AnimatorConditionMode.Equals, (int)temp, "State");
                }
            }
        }
    
        //指定某一个状态能够过渡到退出动画状态
        // states[0].AddExitTransition();
    }

最终选中controller,然后点击CreateAnumator就能生成状态机的参数了:

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

KindSuper_liu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值