Unity 协程使用指南
2016-01-03 16:17
555 查看
0x00 前言
在使用Unity的过程中,对协程只知道如何使用,但并不知道协程的内部机理,对于自己不清楚的部分就像一块大石压力心里,让自己感觉到担忧和不适。这篇文章一探究竟,彻底揭开协程的面纱,让大家在使用中不再有后顾之忧。0x01 概念
协程是:程序组件来生成非抢占式多任务子函数,生成的子函数允许在程序里挂起和唤醒操作。0x02 使用场景
通常协程可以很方便实现延时操作,以及异步加载操作。下面是两个简单协程使用例子。延时操作
// Use this for initialization void Start () { StartCoroutine (Wait ()); } IEnumerator Wait(){ Debug.Log ("start time:" + Time.time); yield return new WaitForSeconds (1); Debug.Log ("time:" + Time.time); yield return new WaitForSeconds(2); Debug.Log ("time:" + Time.time); }
异步加载资源
// Use this for initialization void Start () {; System.Action<string> callBack = delegate(string text) { Debug.Log(text); }; StartCoroutine (LoadRes (callBack)); } IEnumerator LoadRes(System.Action<string> callBack){ WWW www = new WWW ("http://www.baidu.com"); yield return www; if (string.IsNullOrEmpty (www.error)) { callBack(www.text); Debug.Log("load success"); } else{ Debug.Log("load failed"); } }
0x03 原理
Unity里的协程通过定义一个返回 IEnumerator类型的函数,先来通过一个函数看看Unity都能返回那些类型:IEnumerator Test(){ yield return 2; // 返回整数 yield return 4.2; // 返回浮点数 yield return null; // 返回null yield return new WaitForSeconds(1); // 返回instance yield return new WWW ("http://www.baidu.com"); // 返回instance }
返回的类型有什么要求?整理一下Unity都实现了那些返回类型:
1、int类型,需要等待的帧数
2、float类型,需要等待的时间(秒)
3、null,等待一帧
4、break,结束协程
5、实例,必须有bool isDone()成员函数,等isDone返回true
6、IEnumerator,等IEnumerator实例的MoveNext()返回false
Unity的返回类型知道了,如何捕获这些返回类型?来看IEnumerator如何实现的?
public interface IEnumerator { // // Properties // object Current { get; } // // Methods // bool MoveNext (); void Reset (); }
通过研究IEnumerator接口,得到通过调用MoveNext,我们可以得到遍历所有yield返回的值,返回的值可以通过Current得到。每次调用MoveNext都会执行夹在yield中间的代码。写个测试程序来验证我们的理论:
public class game_client : MonoBehaviour { // Use this for initialization void Start () { IEnumerator i = Test (); while (true) { if(!i.MoveNext()){ break; } object cur = i.Current; if(cur != null) Debug.Log(cur.GetType()); else Debug.Log("type is null"); } } IEnumerator Test(){ yield return 2; yield return 4.2; yield return null; yield return new WaitForSeconds(1); yield return new WWW ("http://www.baidu.com"); } }
通过验证程序,可以得到yield返回的值,有了这些值,就可以实现自己的协程。
0x04 实现
设计接口:class ScheduleCoroutine { public void StartCoroutine(IEnumerator coroutine); public void StopCoroutine(IEnumerator coroutine); public void Update(int frame, float time); }
设计数据结构:
class CoroutineNode{ public IEnumerator itor; public string name; public int frame; public float time; public Object instance; public CoroutineNode pre; public CoroutineNode next; }
具体实现代码,对于不同的项目需求,有不同的实现方式。这篇文章主要是探寻Unity协程的实现方式。搞清楚原理后,在使用上就会更加得心应手。
0x05 参考
文章参考了很多其他博文,感谢他们的付出。在第一个参考链接里,有具体实现代码。1、UnifyWiki
2、维基百科
相关文章推荐
- Unity 协程使用指南
- Unity-Animator深入系列---剪辑播放后位置预判(Animator.Target)
- Unity3d PBR海水渲染
- Unity中使用ulua的个人经验总结
- Unity-Animator深入系列---目标匹配Target Matching
- 解决虚拟机的Unity模式无法进入及VM虚拟机安装vmware tools详细操作步骤(图)
- unity, asset operations
- 【u3d】环境搭建
- Unity-Animator深入系列---录制与回放
- 借助TinyXml,C++实现Unity的PlayerPrefs 功能
- unity与3DMax的单位问题
- Unity3D之坐标变化
- Unity3D之float Input.GetAxis(string axisname)
- Unity5脚本事件函数及其执行顺序
- Unity3D 经常使用库
- [转]How to translate WORLD coordinates to TERRAIN coordinates in Unity3d
- Unity-Animator深入系列---StateMachineBehaviour状态机脚本学习
- Unity+NGUI性能优化方法总结
- unity 2D总结(转发 忘记源地址了)
- unity4.6_摄像机跟随模式、观察模式融合(平滑)