Animator自定义动画播放

Animator是个非常强大的动画控制工具,网上基础教程也是很多。
在多数情况下,特别是对人物动作的编辑,我们编辑动画通常使用在Animator连线的方式来实现动作的播放,像这样:在这里插入图片描述
在这里希望分享另外一种非常实用的方式,他的布局可能是这样的:
在这里插入图片描述
动画片段之间并没有太多的连线与过度,在某些情况下我们的动画之间是针对某个物体的。但动画片段之间并不需要太多的关联\连贯性。这时候我推荐使用这种直接播放与连线结合的方式。
好处如下:
1.可能随心所欲的直接跳到想要播放的片段。
2.不用控制太多的状态与分支。
3.采用跳转与连线结合的方式,动作修改插入也非常灵活。
缺点如下:
1.在视图中动画间关系不明显。
2.复杂的动画片段组合无法实现
3.动画过度缺失。

个人认为这个方法并非一个强力推荐的方式,所以在这里提出来也只是多一种方式的选择。下面提供几个代码操作方式给大家参考:
播放动画:

protected void _PlayAnim(Animator anim, string animName)
{
    
    
	if (anim != null)
	{
    
    
    	anim.enabled = true;
    	anim.Play(animName);
    }
    else
    {
    
    
	    Debug.Log("StepHandleBase PlayAnim is error");
    }
}

进度监控
变量:

private Dictionary<string, AnimPragressStruct> m_dicAnimMonitoring;
protected int m_step;
protected AnimatorStateInfo m_animatorInfo;

结构:

	/// <summary>
    /// 监控动画结构
    /// </summary>
    public class AnimPragressStruct
    {
    
    
        public Animator aminator;
        public string name;
        public string keyName;
        public int step;
        public float finish;
        public Action callback;
    }

注册监控:

 	protected virtual void _RegisterAnimPragress(Animator anim, string name, int step, float finish, Action action)
    {
    
    
        if (anim != null && m_dicAnimMonitoring != null)
        {
    
    
            string keyName = anim.name + name;

            if (!m_dicAnimMonitoring.ContainsKey(keyName))
            {
    
    
                AnimPragressStruct s = new AnimPragressStruct();
                s.aminator = anim;
                s.name = name;
                s.keyName = keyName;
                s.step = step;
                s.finish = finish;
                s.callback = action;

                m_dicAnimMonitoring.Add(keyName, s);
            }
        }
        else
        {
    
    
            Debug.Log("StepHandleBase _RegasterAnimMonitoring is null");
        }
    }

放在Update里的监控:
主要是通过这句来监控:aminator.GetCurrentAnimatorStateInfo(0);

 	private void __AnimPragressHandle()
    {
    
    
        if (m_dicAnimMonitoring != null && m_dicAnimMonitoring.Values.Count > 0)
        {
    
    
            Action a = null;
            foreach (AnimPragressStruct s in m_dicAnimMonitoring.Values)
            {
    
    
                if (m_step == s.step && s.aminator != null && s.aminator.enabled)
                {
    
    
                    m_animatorInfo = s.aminator.GetCurrentAnimatorStateInfo(0);
                    if ((m_animatorInfo.normalizedTime >= s.finish) && m_animatorInfo.IsName(s.name) && s.callback != null)
                    {
    
    
                        a = s.callback;
                        break;
                    }
                }
            }
            if (a != null) a();
        }
    }

调用方式如下:
1._PlayAnim(animE3, “GB143_Step3”);
播放animE3中的动画片段GB143_Step3
在这里插入图片描述
2._RegisterAnimMonitoring(animE3, “GB143_Step3”, 31, 1f, __Step32Over);
注册监控进度:GB143_Step3 动画片段,当步骤为31(不需要用到的同学可以去掉),进度为1(0~1),时调用方法__Step32Over
方法到此分享完了!!

心路历程:
最近去了游戏公司,暑假也算是游戏旺季所以最近加班比较忙,发现了不少小技巧也没来的及写上博客。之前很兴奋的发了张图出来也是等到这几天才有空把它写上博客。

总结:
其实相信我和大家一样刚开始也是使用连线的方式去控制一个个动画。可以通过一个或多个状态去控制动画的切换和动画间的过度动画。但跳出做游戏在别的时间动画间的关联并不一定很重要了,随着20个30个动画间的切换整个画面全是线,那时候带来的就不是清晰的动画结构了。而是各种冗余和难以修改,牵一发而动全身,当你想在中间安插一个动画的时候也要格外的小心,因而我尝试使用了这用方式来控制。
还有就是对于完成一个动画的监控,使用这种方式来监控动画也可以更好的制动动画的进度。配合逻辑灵活的知道在哪个百分比下切切换到另一个状态或调用别的事件。
总而言之分享这个方法并非控制的最优解,希望给大家作为一个参考。

猜你喜欢

转载自blog.csdn.net/ww1351646544/article/details/88754980