Unity 动画(UITweener)、协程(Coroutine)和委托(Delegate)队列管理
By D.S.Qiu
尊重他人的劳动,支持原创,转载请注明出处:http.dsqiu.iteye.com
问题
前段时间,项目中要做奖励界面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>(); //implement for IPlay infterface 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); } }
小结:
这是 D.S.Qiu 自己写的一个小管理类,功能也很少,小团队在实际开发中最不能的就是研发,研发太占时间了,所以很多功能都是跟着需求走点到为止。为了写这篇文章今天下午还特意跑回公司,没有备份上面的代码,本来可以写点别的,等明天去公司再做进一步补充,但是D.S.Qiu只要心里有疙瘩,就不能安心去做其他事情,犹豫再三还是跑了趟公司。
如果您对D.S.Qiu有任何建议或意见可以在文章后面评论,或者发邮件(gd.s.qiu@gmail.com)交流,您的鼓励和支持是我前进的动力,希望能有更多更好的分享。
转载请在文首注明出处:http://dsqiu.iteye.com/blog/2031778
更多精彩请关注D.S.Qiu的博客和微博(ID:静水逐风)
参考:
①NGUI EventDelegate: http://www.tasharen.com/ngui/docs/class_event_delegate.html
相关推荐
本文将详细介绍 Unity3D 中的协程(Coroutine)技术,包括为什么需要协程、协程的定义和工作原理、如何使用协程等方面的知识点。 一、为什么需要协程 在游戏中,有许多过程需要花费多个逻辑帧去计算。如果我们不...
Unity协程(Coroutine)原理深入剖析.pdf Unity协程(Coroutine)原理深入剖析.pdf Unity协程(Coroutine)原理深入剖析.pdf Unity协程(Coroutine)原理深入剖析.pdf Unity协程(Coroutine)原理深入剖析.pdf
Unity中的协程(Coroutine)是游戏开发中一种重要的编程机制,它允许开发者在不阻塞主线程的情况下执行异步操作,比如实现动画过渡、延迟执行、持续性逻辑更新等。在Unity引擎中,协程是通过`IEnumerator`接口实现的...
在Unity引擎中,协程(Coroutine)是一种独特的编程机制,它允许开发者在游戏逻辑中实现类似于异步操作的功能,而不必使用回调函数或线程。协程可以暂停执行并在稍后的时间点继续,这对于处理耗时操作如加载资源、...
Unity协程(Coroutine)是Unity引擎中的一个强大特性,它允许开发者在游戏逻辑中实现非阻塞式的长时间运行任务,比如动画播放、网络同步、定时器等。在Unity中,协程是由`IEnumerator`接口定义的,这与C#中的迭代器...
Unity3D是一款强大的跨平台游戏开发引擎,而协程(Coroutine)是Unity中一个非常重要的概念,它允许开发者在执行过程中暂停和恢复一个函数,而不是一次性执行完毕。这对于实现复杂的逻辑,如动画过渡、延时操作、...
为了不阻塞游戏主循环,Unity3D引入了协程(Coroutine)的概念,允许开发者以非阻塞的方式处理长时间运行的任务,比如下载和加载资源。 **协程简介** 协程是一种轻量级的线程,它不像传统的多线程那样需要频繁地上...
在C#编程中,Unity3D引擎提供了一种独特的机制,称为协程(Coroutine),用于处理游戏中的异步操作和长时间运行的任务。协程在Unity中扮演着重要角色,允许开发者编写类似函数的序列,这些序列可以在不同的时间点...
在Unity引擎中,动画系统是游戏开发中的关键组成部分,它允许开发者创建丰富的角色行为和交互。本资源包涉及的主题是“Unity动画冻结、减益、加速”,这些是控制角色动画状态和表现的重要技术。让我们详细探讨一下...
在Unity3D游戏引擎中,协同程序(Coroutine)是一种强大的工具,它允许开发者在执行过程中暂停和恢复函数,实现非阻塞式的时间控制,比如延迟执行、动画播放、定时任务等。然而,有时我们需要在运行时终止这些协同...
在Unity游戏开发中,将Adobe After Effects(简称AE)中的动画导入到Unity是常见的需求,因为AE的强大动画设计能力能够为游戏带来丰富的视觉效果。"ae转unity动画"这一技术涉及多个方面,包括关键帧控制、UI系统兼容...
虽然协程和线程都能实现异步执行,但协程更轻量级,没有线程切换的开销,且易于管理,避免了竞态条件和死锁等问题。然而,协程无法利用多核处理器的优势,如果需要进行大量计算,仍需考虑线程或Unity的Job System。 ...
通过对上述两个代码示例的分析,我们可以看出在Unity3D中使用队列能够有效地帮助我们组织和管理游戏中的各种数据和逻辑。无论是非泛型队列还是泛型队列,都能够根据具体需求选择合适的方式来实现所需的功能。此外,...
总的来说,Unity动画插件Spine包是2D游戏开发者的得力助手,它简化了骨骼动画的创建和管理流程,提供了丰富的功能和优秀的性能。不论是新手还是经验丰富的开发者,都应该掌握其使用方法,以便在Unity项目中创造出...
Simple Mirror Animation Unity动画镜像翻转插件,Mirroring character animations should not just be a Mecanim only feature. With the Simple Mirror Animation asset, legacy character animation mirroring is...
Unity3D 是一个功能强大且广泛应用的游戏引擎,它提供了强大的图形处理能力和动画功能。今天我们将探讨 Unity3D 动画贴图、滚动纹理、滚动贴图脚本的实现细节。 一、动画贴图 动画贴图(Animated Texture)是一种...
在Unity中,动画的实现通常依赖于Unity的动画系统,包括 Animator组件、Animation窗口和Animator控制器。这个资源包可能包含了预设的动画控制器和相关的Sprite动画,开发者可以直接导入到项目中使用,无需从头创建。...
unity 协程详细说明。具体教程http://blog.csdn.net/fengya1/article/details/79380410
本资源包"Unity金币收集及翻转卡片特效.zip"包含了一套实现金币收集和卡片翻转效果的示例项目,对于学习和提升Unity特效的开发者来说极具参考价值。下面,我们将深入探讨这两个关键知识点。 首先,我们来看金币收集...
Unity动画系统是游戏开发者在创建交互式体验时不可或缺的一部分,特别是在3D游戏和虚拟现实应用中。虽然Unity内置的动画系统已经相当强大,但有时它可能无法满足特定项目的需求,这时自定义动画插件就显得尤为重要。...