部分内容参考网址:http://blog.csdn.net/huang9012/article/details/29595747
Win7+U3D 4.6.7
1.在c#中使用
①首选需要定义一个返回值为IEnumerator的协程函数
1 IEnumerator Do(){ 2 Debug.Log("Do 1"); 3 4 yield return 0; //下面的代码延时到下一帧的update之后 5 6 Debug.Log("Do 2"); 7 }
②使用StartCoroutine函数调用协程函数
1 void Start () { 2 Debug.Log("Start 1"); 3 StartCoroutine(Do()); //调用协程函数 4 Debug.Log("Start 2"); 5 }
③在Update函数中输出数字,判断Updata函数和协程之间的执行先后顺序
1 int i = 0; 2 void Update () { 3 ++i; 4 Debug.Log("Update " +i); //这里记录了调用update函数多少次 5 }
④在LateUpdate函数中输出数字,判断LateUpdate函数和协程之间的执行先后顺序
1 int j = 0; 2 void LateUpdate() 3 { 4 ++j; 5 Debug.Log("LateUpdate " + j); //这里记录了调用update函数多少次 6 }
⑤运行的输出顺序结果是:
1 Start 1 2 Do 1 //yield之后再下一帧的update之后继续执行 3 Start 2 4 Update 1//第一帧(当前帧)update执行完 5 LateUpdate 1//第一帧(当前帧)的最后执行 6 Update 2//第二帧(下一帧执行)update执行完 7 Do 2//执行yield之后的代码 8 LateUpdate 2//没错,LateUpdate在协程之后 9 Update 3 10 LateUpdate 3 11 Update 4 12 LateUpdate 4 13 Update 5 14 LateUpdate 5…
2.关于协程的理解:
①在传统实时游戏中,在update中要延迟执行一些代码,或者满足一定条件后执行一些代码。需要在update添加一个计时器,用当前时间来减去前面记录的时间来判断执行。当这种情况越来越多的时候,会添加很多变量和代码,代码就越来越乱,这时候一般会抽象一个框架出来处理这个问题。协程就是解决这种问题的框架,换句话说yield return 0(return的是int值,任何值都一样,没有区别)的作用,就是在调用yield那行代码后(在yield函数处做一个记录标签),然后跳出协程函数继续执行外部的代码,在下一帧(是下一帧!)的update函数之后,根据yield函数的记录标签位置继续执行协程函数的后面部分代码。
②
yield return int是等待下一帧(应用场景:倒计时,分数累加,血条慢慢减少等)
yield return new new WaitForSeconds (2)是等待时间到
yield return new WWW(“http://chevin.net”)是等到页面响应
③协程和Update()一样更新,自然可以使用Time.deltaTime了,而且这个Time.deltaTime和在Update()当中使用是一样的效果(使用yield return int的情况下)
④协程并不是多线程,它和Update()一样是在主线程中执行的,所以不需要处理线程的同步与互斥问题
⑤yield return null其实没什么神奇的,只是unity3d封装以后,这个协程在下一帧就被自动调用了
3.为了更清楚的说明yield return int的下一帧执行的用处,分别使用两种方法实现同一个延时功能。
①使用update不断累加时间
1 using UnityEngine; 2 using System.Collections; 3 4 public class dialog_easy : MonoBehaviour { 5 public string dialogStr = "一个一个字显示"; 6 public float speed = 5.0f; 7 8 private float timeSum = 0.0f; 9 private bool isShowing = false; 10 // Use this for initialization 11 void Start () { 12 ShowDialog(); 13 } 14 15 // Update is called once per frame 16 void Update () { 17 if(isShowing){ 18 timeSum += speed * Time.deltaTime; 19 guiText.text = dialogStr.Substring(0, System.Convert.ToInt32(timeSum)); 20 21 if(guiText.text.Length == dialogStr.Length) 22 isShowing = false; 23 } 24 } 25 26 void ShowDialog(){ 27 isShowing = true; 28 timeSum = 0.0f; 29 } 30 }
②使用yield return int每帧自动调用(明显这种用法简洁明了得多)
1 using UnityEngine; 2 using System.Collections; 3 4 public class dialog_yield : MonoBehaviour { 5 public string dialogStr = "一个一个字显示"; 6 public float speed = 5.0f; 7 8 // Use this for initialization 9 void Start () { 10 StartCoroutine(ShowDialog()); 11 } 12 13 // Update is called once per frame 14 void Update () { 15 } 16 17 IEnumerator ShowDialog(){ 18 float timeSum = 0.0f; 19 while(guiText.text.Length < dialogStr.Length){ 20 timeSum += speed * Time.deltaTime; 21 guiText.text = dialogStr.Substring(0, System.Convert.ToInt32(timeSum)); 22 yield return null; 23 } 24 } 25 }