扩展Coroutine:自定义YieldInstruction
来源:互联网 发布:质量管理体系数据分析 编辑:程序博客网 时间:2024/06/06 03:30
点击打开链接
Unity的Coroutine机制无疑是这个引擎的一个亮点,可以把很多异步的逻辑用一种顺序的书写方式去实现,这个还是很重要的。
关于Coroutine的原理,说实话,这个没有源代码,不好说具体是怎么实现的。看他用到了IEnumerator,想象是使用了.Net的枚举机制。网上有不是探讨Coroutine实现原理的帖子,有兴趣的同学可以翻开看看。
Coroutine之所以强大,缺不了一系列YieldInstruction的派生类,包括:WaitForSeconds , WaitForFixedUpdate,AsyncOperation等等,我一直在琢磨能不能实现自己的YieldInstruction派生类呢?今天花时间尝试了一些,答案是“不能,也能”,哈哈。为什么说“不能”呢,是因为YieldInstruction这个类可没什么虚函数可以去override的,为什么说“能”呢!我们可以借用一个特殊的YieldInstruction派生类,来实现等同的功能,这个类就是Coroutine。
完整的演示工程下载:http://pan.baidu.com/s/1jGGhRKE
这个工程是这样一个例子:
假设我们想实现这样一个YieldInstruction:当一个动画播放完事儿之后,程序再继续。
具体的实现也很简单,首先我们需要一个IEnumerator的派生类,并实现其3个接口,具体代码如下:
- using UnityEngine;
- using System.Collections;
- public class WaitForEndOfAnim : IEnumerator
- {
- AnimationState m_animState;
- public WaitForEndOfAnim(AnimationState animState)
- {
- m_animState = animState;
- }
- //-- IEnumerator Interface
- public object Current
- {
- get
- {
- return null;
- }
- }
- //-- IEnumerator Interface
- public bool MoveNext()
- {
- return m_animState.enabled;
- }
- //-- IEnumerator Interface
- public void Reset()
- {
- }
- }
这里面核心的逻辑就在“MoveNext”函数中,我通过m_animState.enabled来判断动画是否播放完了。
有了这个类时候,如果我们在协程函数体中写:yield return new WaitForEndOfAnim(animState),发现并没有其作用。后来改为:yield return StartCoroutine(new WaitForEndOfAnim(animAttack));就OK了。完整的测试代码如下:
- using UnityEngine;
- using System.Collections;
- public class UnitTest : MonoBehaviour
- {
- // Use this for initialization
- void Start()
- {
- }
- void OnGUI()
- {
- GUILayout.BeginArea(new Rect(6, 6, 200, 300));
- GUILayout.BeginVertical();
- GUILayout.Box("Conrountinue测试");
- if (GUILayout.Button("启动"))
- {
- StartCoroutine(DoTest());
- }
- GUILayout.EndVertical();
- GUILayout.EndArea();
- }
- IEnumerator DoTest()
- {
- Animation anim = GetComponentInChildren<Animation>();
- AnimationState animAttack = anim["attack"];
- animAttack.speed = 0.1f;
- AnimationState animHit = anim["hit"];
- animHit.speed = 0.1f;
- AnimationState animDie = anim["die"];
- animDie.speed = 0.1f;
- Debug.Log("1.开始播放攻击动画。" + Time.time * 1000);
- anim.Play(animAttack.name);
- yield return StartCoroutine(new WaitForEndOfAnim(animAttack));
- Debug.Log("2.开始播放受击动画。" + Time.time * 1000);
- anim.Play(animHit.name);
- yield return StartCoroutine(new WaitForEndOfAnim(animHit));
- Debug.Log("3.开始播放死亡动画。" + Time.time * 1000);
- anim.Play(animDie.name);
- yield return StartCoroutine(new WaitForEndOfAnim(animDie));
- }
- }
- 扩展Coroutine:自定义YieldInstruction
- 扩展Coroutine:自定义YieldInstruction
- coroutine
- coroutine
- Coroutine
- eclipse 自定义扩展点
- Eclipse自定义扩展点
- Google扩展自定义搜索引擎
- eclipse 自定义扩展点
- jquery自定义扩展方法
- 自定义eclipse扩展点
- 自定义扩展点
- WinForm自定义控件扩展
- 扩展OutputDebugString,自定义Trace
- 自定义标签功能扩展
- 自定义SNMP Agent扩展
- Spring PropertyPlaceholderConfigurer 自定义扩展
- openstack 扩展自定义功能
- 在推动或要求的最重要途径的选择电源的网站
- [LeetCode][Java] Permutation Sequence
- TCP处理主要开销
- mark一下
- 【美团技术博客】Hive SQL的编译过程
- 扩展Coroutine:自定义YieldInstruction
- poj3264
- 通过urllib2抓取网页内容(1)
- CVPR2015一些文章整理
- sql2012安装时出现Netfx3相关问题
- 习题1-2 温度(temperature)
- Python3 支持 MySQL
- 2015年7月16号
- 如何跟踪Entity Framework生成的SQL!