unity 协程
2016-06-01 20:27
489 查看
在使用Unity的过程中,对协程只知道如何使用,但并不知道协程的内部机理,对于自己不清楚的部分就像一块大石压力心里,让自己感觉到担忧和不适。这篇文章一探究竟,彻底揭开协程的面纱,让大家在使用中不再有后顾之忧。
协程是:程序组件来生成非抢占式多任务子函数,生成的子函数允许在程序里挂起和唤醒操作。通常协程可以很方便实现延时操作,以及异步加载操作。下面是两个简单协程使用例子。
延时操作:
异步加载资源:
01.// Use this for initialization
02.void Start () {;
03.System.ActioncallBack = delegate(string text) {
04.Debug.Log(text);
05.};
06.StartCoroutine (LoadRes (callBack));
07.}
08.
09.IEnumerator LoadRes(System.ActioncallBack){
10.WWW www = new WWW ('http://www.baidu.com');
11.yield return www;
12.
13.if (string.IsNullOrEmpty (http://www.error))
{
14.callBack(http://www.text);
15.Debug.Log('load success');
16.}
17.else{
18.Debug.Log('load failed');
19.}
20.}
原理:
Unity里的协程通过定义一个返回
IEnumerator类型的函数,先来通过一个函数看看Unity都能返回那些类型:
1.IEnumerator Test(){
2.yield return 2; // 返回整数
3.yield return 4.2; // 返回浮点数
4.yield return null; // 返回null
5.yield return new WaitForSeconds(1); // 返回instance
6.yield return new WWW ('http://www.baidu.com');
// 返回instance
7.}
返回的类型有什么要求?整理一下Unity都实现了那些返回类型:
1、int类型,需要等待的帧数
2、float类型,需要等待的时间(秒)
3、null,等待一帧
4、break,结束协程
5、实例,必须有bool isDone()成员函数,等isDone返回true
6、IEnumerator,等IEnumerator实例的MoveNext()返回false
Unity的返回类型知道了,如何捕获这些返回类型?来看IEnumerator如何实现的?
public interface IEnumerator
02.{
03.//
04.// Properties
05.//
06.object Current
07.{
08.get;
09.}
10.
11.//
12.// Methods
13.//
14.bool MoveNext ();
15.
16.void Reset ();
17.}
通过研究IEnumerator接口,得到通过调用MoveNext,我们可以得到遍历所有yield返回的值,返回的值可以通过Current得到。每次调用MoveNext都会执行夹在yield中间的代码。写个测试程序来验证我们的理论:
01.publicclass game_client : MonoBehaviour {
02.
03.// Use this for initialization
04.void Start () {
05.IEnumerator i = Test ();
06.while (true) {
07.if(!i.MoveNext()){
08.break;
09.}
10.object cur = i.Current;
11.if(cur != null)
12.Debug.Log(cur.GetType());
13.else
14.Debug.Log('type is null');
15.}
16.}
17.
18.
19.IEnumerator Test(){
20.yield return 2;
21.yield return 4.2;
22.yield return null;
23.yield return new WaitForSeconds(1);
24.yield return new WWW ('http://www.baidu.com');
25.}
26.}
通过验证程序,可以得到yield返回的值,有了这些值,就可以实现自己的协程。
实现
设计接口:
1.
2.{
3.public void StartCoroutine(IEnumerator coroutine);
4.public void StopCoroutine(IEnumerator coroutine);
5.public void Update(int frame, float time);
6.}
设计数据结构:
01.
02.public IEnumerator itor;
03.public string name;
04.public int frame;
05.public float time;
06.public Object instance;
07.public CoroutineNode pre;
08.public CoroutineNode next;
09.}
具体实现代码,对于不同的项目需求,有不同的实现方式。这篇文章主要是探寻Unity协程的实现方式。搞清楚原理后,在使用上就会更加得心应手。
协程是:程序组件来生成非抢占式多任务子函数,生成的子函数允许在程序里挂起和唤醒操作。通常协程可以很方便实现延时操作,以及异步加载操作。下面是两个简单协程使用例子。
延时操作:
02.void Start () { 03.StartCoroutine (Wait ()); 04.} 05. 06.IEnumerator Wait(){ 07.Debug.Log ('start time:' + Time.time); 08.yield return new WaitForSeconds (1); 09.Debug.Log ('time:' + Time.time); 10.yield return new WaitForSeconds(2); 11.Debug.Log ('time:' + Time.time); 12.}
异步加载资源:
01.// Use this for initialization
02.void Start () {;
03.System.ActioncallBack = delegate(string text) {
04.Debug.Log(text);
05.};
06.StartCoroutine (LoadRes (callBack));
07.}
08.
09.IEnumerator LoadRes(System.ActioncallBack){
10.WWW www = new WWW ('http://www.baidu.com');
11.yield return www;
12.
13.if (string.IsNullOrEmpty (http://www.error))
{
14.callBack(http://www.text);
15.Debug.Log('load success');
16.}
17.else{
18.Debug.Log('load failed');
19.}
20.}
原理:
Unity里的协程通过定义一个返回
IEnumerator类型的函数,先来通过一个函数看看Unity都能返回那些类型:
1.IEnumerator Test(){
2.yield return 2; // 返回整数
3.yield return 4.2; // 返回浮点数
4.yield return null; // 返回null
5.yield return new WaitForSeconds(1); // 返回instance
6.yield return new WWW ('http://www.baidu.com');
// 返回instance
7.}
返回的类型有什么要求?整理一下Unity都实现了那些返回类型:
1、int类型,需要等待的帧数
2、float类型,需要等待的时间(秒)
3、null,等待一帧
4、break,结束协程
5、实例,必须有bool isDone()成员函数,等isDone返回true
6、IEnumerator,等IEnumerator实例的MoveNext()返回false
Unity的返回类型知道了,如何捕获这些返回类型?来看IEnumerator如何实现的?
public interface IEnumerator
02.{
03.//
04.// Properties
05.//
06.object Current
07.{
08.get;
09.}
10.
11.//
12.// Methods
13.//
14.bool MoveNext ();
15.
16.void Reset ();
17.}
通过研究IEnumerator接口,得到通过调用MoveNext,我们可以得到遍历所有yield返回的值,返回的值可以通过Current得到。每次调用MoveNext都会执行夹在yield中间的代码。写个测试程序来验证我们的理论:
01.publicclass game_client : MonoBehaviour {
02.
03.// Use this for initialization
04.void Start () {
05.IEnumerator i = Test ();
06.while (true) {
07.if(!i.MoveNext()){
08.break;
09.}
10.object cur = i.Current;
11.if(cur != null)
12.Debug.Log(cur.GetType());
13.else
14.Debug.Log('type is null');
15.}
16.}
17.
18.
19.IEnumerator Test(){
20.yield return 2;
21.yield return 4.2;
22.yield return null;
23.yield return new WaitForSeconds(1);
24.yield return new WWW ('http://www.baidu.com');
25.}
26.}
通过验证程序,可以得到yield返回的值,有了这些值,就可以实现自己的协程。
实现
设计接口:
1.
2.{
3.public void StartCoroutine(IEnumerator coroutine);
4.public void StopCoroutine(IEnumerator coroutine);
5.public void Update(int frame, float time);
6.}
设计数据结构:
01.
02.public IEnumerator itor;
03.public string name;
04.public int frame;
05.public float time;
06.public Object instance;
07.public CoroutineNode pre;
08.public CoroutineNode next;
09.}
具体实现代码,对于不同的项目需求,有不同的实现方式。这篇文章主要是探寻Unity协程的实现方式。搞清楚原理后,在使用上就会更加得心应手。
相关文章推荐
- 一些不错的文章链接记录
- Unity中导出iOS工程
- Unity资源加载与释放
- Unity3d Jenkins 打包Android
- unity学习笔记(1)-hello unity
- 游戏表格数据序列化自动生成工具
- 在unity向量空间内绘制几何(2):球面---重构《黑客帝国》的‘上帝机器’,Deus Ex Machina
- unity 常用的几种相机跟随
- Unity3D场景异步加载的实现案例
- Unity开发者如何使用VS进行单步,详情点击
- 【Unity】新手引导遮罩
- 【Unity】安卓/ios应用名本地化
- Unity3D获取物体的所有子物体对象(child)
- Unity3D写雷电游戏
- Unity让调试更加简单(一)
- Unity3D之Vector3.Dot(点积)和Vector3.Cross(叉积)的使用
- unity规范
- UnityShader快速上手指南(三)
- UnityShader快速上手指南(三)
- 帮同学做的把T1图像转成TXT格式用于unity 3d输入的小工具