标签:unity3d培训 unity3d游戏 unity培训 unity3d学习
问题
前段时间,项目中要做奖励界面UI缓动动画要一个接着一个播放,如:先播放达成星星动画,在播放经验数字增加动画,最后播放奖励物品动画。
当然最笨最直接的方法可以类似成语接龙那样,把下个动画的开始播放都写在上一个动画播放完毕委托中。一般直接的方法是实现起来非常之简单,但这里却不是,会看见代码中有一系列播放完毕回调函数(除了最后一个),显然维护起来是否费劲。
把上面的方法进行简化,把回调函数变为一个:维护一个动画的 List 和当前播放动画的索引 index ,然后再回调函数中只需要让 index 递增 播放动画就可以了。这个方法比上面成语接龙方法改进的地方在于只需要维护List中动画的顺序,不用还要做首尾结合的工作了。
上面的问题之所以会觉得有点棘手是因为动画是在一个时间片段上“连续”执行的,这里的“时间片段”不是计算机概念上的 time slot 。在使用协程和延时委托也会遇到同样的问题,本来就是介绍使用队列对动画,协程和委托的管理,只需要关心彼此在队列的次序。
IPlay定义
先定义了一个借口 IPlay 有两个方法:
Begin() ,动画,协程 开始执行方法
OnEnd ,动画,协程 执行完毕的回调函数(委托队列)
这里的 EventDelegate 类型是 NGUI 定义的, 可以查看参考①。 IPay 只是定义了 开始 和 结束 两个状态,其实是在 上一个 OnEnd 中执行了下一个 的 Begin 方法。
-
using System;
-
using System.Collections.Generic;
-
public interface IPlay
-
{
-
List<EventDelegate> OnEnd
-
{
-
get;
-
}
-
void Begin();
-
}
实现IPlay
在项目中,主要是使 UITweener 实现了 IPlay ,UITweener 本来就支持IPlay的这两个方法,只是封装下就可以了:
-
public abstract class UITweener : MonoBehaviour,IPlay
-
{
-
[HideInInspector]
-
public List<EventDelegate> onFinished = new List<EventDelegate>();
-
-
public List<EventDelegate> OnEnd
-
{
-
get{
-
return onFinished;
-
}
-
}
-
public void Begin()
-
{
-
ResetToBeginning();
-
if(amountPerDelta>0)
-
PlayForward();
-
else if(amountPerDelta<0)
-
PlayReverse();
-
}
-
-
}
协程实现IPlay
协程是通过前面介绍的 TaskManager (点击查看)来实现 IPlay的方法的:
-
public class Task :IPlay
-
{
-
public List<EventDelegate> onFinish = new List<EventDelegate>();
-
-
public List<EventDelegate> OnEnd
-
{
-
get{
-
return onFinish;
-
}
-
}
-
public void Begin()
-
{
-
task.Start();
-
}
-
-
}
PlayList——实现队列管理
PlayList就是维护了 IPlay 的 List ,先往 playList 中添加 IPlay ,然后通过调用 ContactPlay 把 IPlay 安装先后次序连接起来,直接贴出源码:
-
using UnityEngine;
-
using System.Collections;
-
using System.Collections.Generic;
-
public class PlaytList {
-
public List<IPlay> playList = new List<IPlay>();
-
-
private int index = 0;
-
public void AddPlay(IPlay play,int index = -1)
-
{
-
if(play == null)
-
return;
-
if(index == -1)
-
playList.Add(play);
-
else if(index < 0 || index > playList.Count)
-
return;
-
else
-
playList.Insert(index,play);
-
}
-
-
public void AddTimeInterval(float seconds,int index = -1)
-
{
-
AddPlay(WaitForSeconds(seconds),index);
-
}
-
-
public void AddCoroutine(IEnumerator coroutine,int index = -1)
-
{
-
AddPlay(new Task(coroutine,false),index);
-
}
-
private void ContatPlay()
-
{
-
for(int i =0,length = playList.Count-1;i<length;i++)
-
{
-
EventDelegate.Add (playList[i].OnEnd,PlayNext);
-
}
-
}
-
public void ClearPlay()
-
{
-
playList.Clear();
-
}
-
public void Start()
-
{
-
ContatPlay();
-
index = 0;
-
if(playList.Count>0)
-
playList[0].Begin();
-
}
-
private void PlayNext()
-
{
-
index ++;
-
if(index >= playList.Count)
-
return;
-
else
-
playList[index].Begin();
-
-
}
-
public Task WaitForSeconds(float seconds)
-
{
-
return new Task(WaitForSecondsHandle(seconds),false);
-
}
-
IEnumerator WaitForSecondsHandle(float seconds)
-
{
-
yield return new WaitForSeconds(seconds);
-
}
-
}
更多unity3d技术,请访问 【狗刨学习网】http://unity.gopedu.com
声明:此篇文档时来自于【狗刨学习网】社区,是网友自行发布的Unity3D学习文章,如果有什么内容侵犯了你的相关权益,请与官方沟通,我们会即时处理。
Unity 动画(UITweener)、协程(Coroutine)和委托(Delegate)队列管理
标签:unity3d培训 unity3d游戏 unity培训 unity3d学习
原文地址:http://blog.csdn.net/book_longssl/article/details/43567381