Unity中Animator组件Runtime控制动画的正向和反向播放

        最初的想法是希望能够完全不改变美工的工作流程,通过代码解决所有问题。但是以笔者目前的认知水平还不行,还得麻烦一下美工,郁闷。

        本来以为Animator.speed这个值设置为负数就可以倒播动画了,但是实际上设置为小于0的数和0没有区别,就是等同于暂停而已。

        那么剩下就是改AnimatorState的speed了。本来以为只要获取到当前的AnimatorState就好办了,但是发现这是不可能的!你只能通过GetCurrentAnimatorStateInfo获取到当前的AnimatorStateInfo,而AnimatorStateInfo的speed值是只读的,国内国外搜了好几圈,没找到能在运行时获取AnimatorState的办法。

        那就只能麻烦美工了,如图:

Unity中Animator组件Runtime控制动画的正向和反向播放_第1张图片

        默认的AnimatorState是moveUpDown,复制这个AnimatorState,改名叫moveUpDown-1,Speed改成-1,这样虽然两个AnimatorState引用的是一个AnimatorClip,但是一个可以正向播放,一个可以反向播放。

        不过还有问题,如果使用Animator.Play(string stateName)这个重载去播放的话,每次都是重头播放,这样假如用户正向播放动画的时候,如果在动画没有播放到结尾就选择倒播,我们会发现动画不是在当前状态开始倒播,而是从结尾往回倒播,这样就会产生跳跃感。解决的办法就是,先获取当前动画已经正向播放了的归一化时间,就是Animator.normalizedTime,用1-Animator.normalizedTime这个时间作为开始反向播放的其实时间就好了,代码上用的是Animator.Play(string stateName,int layer,float normalizedTime)这个重载。反向播放改正向播放道理一样。

        代码示例如下:

using UnityEngine;

public class AnimOnOff : MonoBehaviour
{
	[SerializeField]
	[Header("可暂停动画")]
	Animator[] anims;

	public void Play(float playSpeed)
	{
		bool enabled = !Mathf.Approximately(playSpeed, 0);

		if (anims != null)
		{
			foreach (Animator anim in anims)
			{
				if (!anim) continue;
				//
				anim.enabled = enabled;

				if (anim.enabled)
				{
					AnimatorClipInfo clipInfo = anim.GetCurrentAnimatorClipInfo(0)[0];
					AnimationClip clip = clipInfo.clip;
					if (!clip)
					{
						Debug.Log("ULog:animator clip is null.");
						continue;
					}

					string clipName = clip.name;

					if (clipName.Contains("-1"))
					{
						if (playSpeed > 0)
						{
							clipName = clipName.Replace("-1", "");
						}
					}
					else
					{
						if (playSpeed < 0)
						{
							clipName += "-1";
						}
					}
					AnimatorStateInfo stateInfo = anim.GetCurrentAnimatorStateInfo(0);
					float startPlayTime = stateInfo.normalizedTime;
					if (!stateInfo.IsName(clipName))
						startPlayTime = 1 - startPlayTime;

					anim.speed = Mathf.Abs(playSpeed);
					anim.Play(clipName, 0, startPlayTime);
				}
			}
		}
	}
}

        playSpeed形参获取的值如果是0,那么动画就停止了,如果是正数就正播,负数就倒播,绝对值的大小会影响播放速度。

你可能感兴趣的:(Unity心得,Animator,Unity)