功能实现:Unity中一个动画,只播放中间指定的一截,而且循环播放

一、要播放的动画(直播中间一截)

如图:总的动画为长度为2分钟零8秒
在这里插入图片描述

二、Button和对应事件

在这里插入图片描述

三、事件的代码

在Start()里面绑定

private void Awake()
{
   myAnim = animGo.GetComponent<Animation>();
   
   //【循环播放自定义段落】事件侦听
   BtnPlayLoop.onClick.AddListener(async () =>
   {
       var skipFirstFrameTime = 1 / myAnim[myAnim.clip.name].clip.frameRate;      //跳过一帧的时间是多少【第一帧是初始姿势,需要排除】
       stopLoop = false;

       while (!stopLoop)
       {
           myAnim[myAnim.clip.name].time = skipFirstFrameTime;                     //跳过第一帧
           myAnim.Play(myAnim.clip.name);                                          //Play()
           await UniTask.DelayFrame(1);                                            //帧延缓,等Play()启动

           //方式一:播放到中间指定的进度点则停止                                                                           
           //await UniTask.WaitUntil(()=>myAnim[myAnim.clip.name].time > endTime); //播放进度到达某点的时候
           //myAnim.Stop();                                                        //停止播放

           //方式二:播放到末尾(动画属性设置成once)
           await UniTask.WaitUntil(() => myAnim.isPlaying == false);               //等待播放结束【myAnim.isPlaying == false】
       }            
   });

   //【停止循环播放】事件侦听
   BtnStopLoop.onClick.AddListener(async() => 
   {
       stopLoop = true;

       myAnim[myAnim.clip.name].time = myAnim[myAnim.clip.name].length; //这一句用于跳到结束位,酌情添加
       await UniTask.DelayFrame(1);                                     //配合上一句服用:延缓一帧,用于渲染

       myAnim.Stop();           
   });
}

四、总结

本文所涉及动画播放控制的异步用UniTask包(GitHub地址自行谷歌)实现。用异步实现,逻辑清晰,好控制,不容易被自己绕晕。
【1】凡是涉及渲染处理的那部分,都丢到Update里面
【2】凡是涉及时序控制的,都用丢到一个异步方法里面

  • 2
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
如果你使用数组来管理多个动画,并且只播放了最后一个动画,那么可能是因为你在循环重复调用了Animator.Play方法,导致前面的动画被覆盖了。为了解决这个问题,你需要在每个动画播放完成后再播放一个动画。 以下是一个修正后的示例代码: ``` // 获取Animator组件 Animator animator = GetComponent<Animator>(); // 定义动画名称数组 string[] animationNames = new string[] {"AnimationA", "AnimationB", "AnimationC"}; // 定义动画状态数组 AnimatorStateInfo[] animationStates = new AnimatorStateInfo[animationNames.Length]; // 播放一个动画 animator.Play(animationNames[0], -1, 0f); animationStates[0] = animator.GetCurrentAnimatorStateInfo(0); // 播放所有其他动画 for (int i = 1; i < animationNames.Length; i++) { // 等待上一个动画播放完成 while (!animationStates[i - 1].IsName(animationNames[i - 1])) { yield return null; } // 播放一个动画 animator.Play(animationNames[i], -1, 0f); animationStates[i] = animator.GetCurrentAnimatorStateInfo(0); } // 等待所有动画播放完成 while (!animationStates[animationNames.Length - 1].IsName(animationNames[animationNames.Length - 1])) { yield return null; } ``` 在上面的代码,我们首先播放了第一个动画,并将它的状态保存到动画状态数组。然后,我们使用一个循环播放所有其他的动画。在循环,我们使用一个while循环来等待上一个动画播放完成。一旦上一个动画播放完成,我们就播放一个动画,并将它的状态保存到动画状态数组。 最后,我们再使用一个while循环来等待所有动画播放完成。在这个循环,我们检查最后一个动画是否播放完成,一旦完成就退出循环。 通过这种方法,我们可以确保每个动画都能够按顺序播放,并且可以等待每个动画播放完成后再播放一个动画
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值