[Unity]协同程序(Coroutine)的基础应用

在之前的foreach原理中有提到过yield return的结合使用;yield关键字就是属于协程的内容,这篇随笔记录一下协程的内容:

定义:

具有多个返回点(yield),可以在特定时机分步执行的函数。

原理:

Unity每帧处理GameObject中的协同函数,直到函数执行完毕。

当一个协同函数启动时,本质创建迭代器对象;调用MoveNext方法,执行到yield暂时退出;待满足条件后再次调用MoveNext方法,执行后续代码,直至遇见下一个yield为止,如此循环至整个函数结束。

语法:

通过MonoBehaviour中的StarCoroutine方法启动,StopCoroutine方法停止。

协程函数返回值类型为IEnumerator,方法体中通过yield关键字定义返回点,通过return XX对象定义继续执行的条件。

可以被yield return的对象:

  1. null或数字 -- Update后执行,适合分解耗时的逻辑处理。
  2. WaitForFixedUpdate -- FixedUpdate后执行,适合分解物理操作。
  3. WaitForSeconds -- 在指定时间后执行,适合延迟调用。

WaitForSecondsRealtime -- 同上,不受时间缩放影响。

    4.WaitForEndOfFrame -- 在每帧结束后执行,适合相机的跟随操作。

    5.Coroutine -- 在另一个协程执行完毕后再执行。

   6.WaitUntil -- 在委托返回true时执行,适合等待某一操作。

     WaitWhile -- 在委托返回false时执行,适合等待某一操作。

   7.WWW -- 在请求结束后执行,适合加载数据,如文件、贴图、材质等。

作用:

  1. 延时调用,很好理解。
  2. 分解调用,可用于物体淡出,颜色渐变等。

简单做一段Cube颜色淡入的代码演示:

 

 

 

使用代码控制Cube的材质球,使其Colora值从0匀速提升到255.

public class CoroutineTest : MonoBehaviour

{

    public GameObject cube;

    public Material cubeMaterial;

    public float fadeSpeed = 0.2f;//大慨五秒淡入完成

 

    private Color colorTemp;

 

    // Start is called before the first frame update

    void Start()

    {

        cubeMaterial = cube.GetComponent<Renderer>().material;

        colorTemp = cubeMaterial.color;

        colorTemp.a = 0;

 

        StartCoroutine(FadeIn());

    }

 

    private IEnumerator FadeIn()

    {

        while (colorTemp.a <= 1)

        {

            cubeMaterial.color = colorTemp;

            colorTemp.a += fadeSpeed * Time.deltaTime;

            yield return null;

        }

    }

}

做个小扩展,既然做了匀速渐变,当然也可以做个变速的渐变,此时可以用AnimationCurve来实现(动画曲线AnimationCurve可以提供数值可视化的操作面板):

 

 

 

public class CoroutineTest : MonoBehaviour
{
    public GameObject cube;
    public Material cubeMaterial;
    public float fadeSpeed = 0.2f;//大概五秒淡入完成

    private Color colorTemp;

    //变速渐变
    public AnimationCurve aniCurve;
    private float time;

    // Start is called before the first frame update
    void Start()
    {
        cubeMaterial = cube.GetComponent<Renderer>().material;
        colorTemp = cubeMaterial.color;
        colorTemp.a = 0;
        time = 0;
        StartCoroutine(FadeIn());
    }

    //变速渐变
    private IEnumerator FadeIn()
    {
        while (colorTemp.a <= 1)
        {
            time += Time.deltaTime;
            cubeMaterial.color = colorTemp;
            colorTemp.a = aniCurve.Evaluate(time * fadeSpeed);
            yield return null;
        }
    }
}

其中AnimationCurve.Evaluate()用来获取参数值x对应的y值,比如该曲线:

 

 

此时AnimationCurve.Evaluate(0.5)的返回值为0.25

如果想做比如红色到蓝色的变化,可以加入Color.Lerp(Color a,Color b,float t)

 

posted @ 2020-12-09 22:11  穷在闹市  阅读(400)  评论(0)    收藏  举报