Unity 动画(UITweener)、协程(Coroutine)和委托(Delegate)队列管理

问题

        前段时间,项目中要做奖励界面UI缓动动画要一个接着一个播放,如:先播放达成星星动画,在播放经验数字增加动画,最后播放奖励物品动画。

        当然最笨最直接的方法可以类似成语接龙那样,把下个动画的开始播放都写在上一个动画播放完毕委托中。一般直接的方法是实现起来非常之简单,但这里却不是,会看见代码中有一系列播放完毕回调函数(除了最后一个),显然维护起来是否费劲。

        把上面的方法进行简化,把回调函数变为一个:维护一个动画的 List 和当前播放动画的索引 index ,然后再回调函数中只需要让 index 递增 播放动画就可以了。这个方法比上面成语接龙方法改进的地方在于只需要维护List中动画的顺序,不用还要做首尾结合的工作了。

 

        上面的问题之所以会觉得有点棘手是因为动画是在一个时间片段上“连续”执行的,这里的“时间片段”不是计算机概念上的 time slot 。在使用协程和延时委托也会遇到同样的问题,本来就是介绍使用队列对动画,协程和委托的管理,只需要关心彼此在队列的次序。

         

 IPlay定义  

         先定义了一个借口 IPlay 有两个方法:

                Begin() ,动画,协程 开始执行方法

                OnEnd ,动画,协程 执行完毕的回调函数(委托队列)

这里的 EventDelegate 类型是 NGUI 定义的, 可以查看参考①。 IPay 只是定义了 开始 和 结束 两个状态,其实是在 上一个 OnEnd 中执行了下一个 的 Begin 方法。

C#代码  技术分享
  1. using System;  
  2. using System.Collections.Generic;  
  3. public interface IPlay  
  4. {  
  5.     List<EventDelegate> OnEnd  
  6.     {  
  7.         get;  
  8.     }  
  9.     void Begin();  
  10. }  

实现IPlay

       在项目中,主要是使 UITweener 实现了 IPlay ,UITweener 本来就支持IPlay的这两个方法,只是封装下就可以了:

C#代码  技术分享
  1. public abstract class UITweener : MonoBehaviour,IPlay  
  2. {  
  3.         [HideInInspector]  
  4.     public List<EventDelegate> onFinished = new List<EventDelegate>();  
  5.     //implement for IPlay infterface  
  6.     public List<EventDelegate> OnEnd  
  7.     {  
  8.         get{  
  9.             return onFinished;  
  10.         }  
  11.     }  
  12.     public void Begin()  
  13.     {  
  14.         ResetToBeginning();  
  15.         if(amountPerDelta>0)  
  16.             PlayForward();  
  17.         else if(amountPerDelta<0)  
  18.             PlayReverse();  
  19.     }  
  20.         //省略其他代码  
  21. }  

 

协程实现IPlay

       协程是通过前面介绍的 TaskManager (点击查看)来实现 IPlay的方法的:

C#代码  技术分享
  1. public class Task :IPlay  
  2. {  
  3.         public List<EventDelegate> onFinish = new List<EventDelegate>();  
  4.   
  5.         public List<EventDelegate> OnEnd  
  6.         {  
  7.             get{  
  8.                 return onFinish;  
  9.             }  
  10.         }  
  11.         public void Begin()  
  12.         {  
  13.             task.Start();  
  14.         }  
  15.                 //省略其他代码  
  16. }  

 

PlayList——实现队列管理

          PlayList就是维护了 IPlay 的 List ,先往 playList 中添加 IPlay ,然后通过调用 ContactPlay 把 IPlay 安装先后次序连接起来,直接贴出源码:

C#代码  技术分享
  1. using UnityEngine;  
  2. using System.Collections;  
  3. using System.Collections.Generic;  
  4. public class PlaytList {  
  5.     public List<IPlay> playList = new List<IPlay>();  
  6.   
  7.     private int index = 0;  
  8.     public void AddPlay(IPlay play,int index = -1)  
  9.     {  
  10.         if(play == null)  
  11.             return;  
  12.         if(index == -1)  
  13.             playList.Add(play);  
  14.         else if(index < 0 || index > playList.Count)  
  15.             return;  
  16.         else  
  17.             playList.Insert(index,play);  
  18.     }  
  19.         //添加 时间间隔  
  20.     public void AddTimeInterval(float seconds,int index = -1)  
  21.     {  
  22.         AddPlay(WaitForSeconds(seconds),index);  
  23.     }  
  24.         //添加 协程  
  25.     public void AddCoroutine(IEnumerator coroutine,int index = -1)  
  26.     {  
  27.         AddPlay(new Task(coroutine,false),index);  
  28.     }  
  29.     private void ContatPlay()  
  30.     {  
  31.         for(int i =0,length = playList.Count-1;i<length;i++)  
  32.         {  
  33.             EventDelegate.Add (playList[i].OnEnd,PlayNext);  
  34.         }  
  35.     }  
  36.     public void ClearPlay()  
  37.     {  
  38.         playList.Clear();  
  39.     }  
  40.     public void Start()  
  41.     {  
  42.         ContatPlay();  
  43.         index = 0;  
  44.         if(playList.Count>0)  
  45.             playList[0].Begin();  
  46.     }  
  47.     private void PlayNext()  
  48.     {  
  49.         index ++;  
  50.         if(index >= playList.Count)  
  51.             return;  
  52.         else  
  53.             playList[index].Begin();  
  54.   
  55.     }  
  56.     public Task WaitForSeconds(float seconds)  
  57.     {  
  58.         return new Task(WaitForSecondsHandle(seconds),false);  
  59.     }  
  60.     IEnumerator WaitForSecondsHandle(float seconds)  
  61.     {  
  62.         yield return new WaitForSeconds(seconds);  
  63.     }  
  64. }  

 

 更多unity3d技术,请访问 【狗刨学习网】http://unity.gopedu.com


 声明:此篇文档时来自于【狗刨学习网】社区,是网友自行发布的Unity3D学习文章,如果有什么内容侵犯了你的相关权益,请与官方沟通,我们会即时处理。

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。