协同程序(Coroutine),顾名思义,即在主程序运行时开启另一端逻辑,来和主程序一同运行。
例如:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class coroutine_test : MonoBehaviour {
// Use this for initialization
void Start ()
{
StartCoroutine("Delay",3f);//开启一个名为Delay的协同,并为其传递一个参数“3”
Debug.Log("3"+"time:"+Time.time);
}
// Update is called once per frame
void Update () {}
IEnumerator Delay(float delaytime)//协同函数
{
print("1"+"time:"+Time.time);
yield return new WaitForSeconds(delaytime);
Debug.Log("2"+"time:"+Time.time);
}
}
最终运行结果:
可以看到,当我们以StartCoroutine来在主程序中开启了Delay的时候,主程序与Delay在同时运行。
在接触Coroutine之前,当游戏里需要使用延时的时候,一般要设置StartTime和DelayTime,然后在Update里面一遍遍检测来完成延时。但使用yield return Coroutine(中断式协同),却可以很简单的完成。
例如:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class coroutine_test : MonoBehaviour {
// Use this for initialization
IEnumerator Start ()
{
Debug.Log("0" + "time:" + Time.time);
yield return StartCoroutine("Delay", 3f);//开启一个名为Delay的协同,并为其传递一个参数“3”
Debug.Log("3"+"time:"+Time.time);
}
// Update is called once per frame
void Update () {}
IEnumerator Delay(float delaytime)//协同函数
{
print("1"+"time:"+Time.time);
yield return new WaitForSeconds(delaytime);//等待一定的时间
Debug.Log("2"+"time:"+Time.time);
}
}
最终结果:
显而易见,上例中主程序等待协同函数执行完毕后才继续向下执行 。
总结:(1)启动协同函数时要使用StartCoroutine(协同工作)或者 yield return StartCoroutine(中断式协同工作),当使用yield return StartCoroutin时,主函数(即yield return StartCoroutine语句所在的函数)的返回值类型必须为IEnumerator,当使用StartCoroutine时则不能为IEnumerator。(2)协同函数的返回值类型必须为IEnumerator。(3)在协同函数中延时语句为yield return new WaitForSeconds()。
无论是协同还是中断式协同,都可以实现多重嵌套协同,例如:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class coroutine_test : MonoBehaviour {
// Use this for initialization
IEnumerator Start ()
{
Debug.Log("0" + "time:" + Time.time);
yield return StartCoroutine("Delay", 3f);//开启一个名为Delay的协同,并为其传递一个参数“3”
Debug.Log("5"+"time:"+Time.time);
}
// Update is called once per frame
void Update () {}
IEnumerator Delay(float delaytime)//协同函数
{
yield return new WaitForSeconds(delaytime);
print("1"+"time:"+Time.time);
yield return StartCoroutine("Delay1",2f);//在Delay函数中嵌套协同函数Delay1函数,并使用中断协同
Debug.Log("4"+"time:"+Time.time);
}
IEnumerator Delay1(float delaytime)//协同函数
{
print("2" + "time:" + Time.time);
yield return new WaitForSeconds(delaytime);//等待一定的时间
Debug.Log("3" + "time:" + Time.time);
}
}
使用StartCoroutine(string methodName)和StartCoroutine(IEnumerator routine)都可以开启协同。
区别在于使用字符串作为参数可以开启协同并在其自动结束前主动终止,
相反使用IEnumerator 作为参数只能等待协同自动结束而不能随时终止(除非使用StopAllCoroutines()方法);
另外使用字符串作为参数时,开启协同时最多只能向协同函数里传递一个参数(例如:yield return StartCoroutine("Delay ",3f);),
并且性能消耗会更大一点,而使用IEnumerator 作为参数则没有这个限制(例如:yield return StartCoroutine(Delay(3f,2f));)。
使用StopCoroutine(string methodName)来终止一个协同程序,使用StopAllCoroutines()来终止所有可以终止的协同程序,
StopCoroutine("Test");
StartCoroutine("Test2",1);
StopCoroutine("Test2");
StartCoroutine(coroutine );
StopCoroutine(coroutine);
IEnumrator coroutine1 = Test2(1);
StartCoroutine(coroutine1 );
StopCoroutine(coroutine1 );
IEnumrator coroutine1 = Test();
IEnumrator coroutine2 = Test();
StartCoroutine(coroutine1 );
StopCoroutine(coroutine2 );