unity update 协程_Unity中关于协程的些许理解

1.什么是协程?

从字面意思来理解,可以是:协助主程序的

程序;比较官方一点的解释是:在主程序执行时,开辟一段逻辑处理

2.在Unity中协程的用法

使用协程分两步:通过StartCorutine调用协程的逻辑方法

完善协程的逻辑方法,返回值是IEnumrator,通过关键字yield来实现

StarCorotine Demo:

void Awake()

{

StartCoroutine(SayHello());

}

private IEnumerator SayHello()

{

for (int i = 0; i < 10; i++)

{

Debug.Log("逻辑处理片段....begin");

Debug.Log("current unit :..............." + i);

yield return 2.0f;

Debug.Log("逻辑处理片段....end");

}

}

3.协程的实现原理:

协程其实是单线程下的异步处理,只是让程序看起来是异步的;通常的应用场景有,进入场景的加载页面,事件的延时操作等.

协程的实现基于C#中的迭代器,具体关于C#迭代器的介绍可以访问:

StartCorotine其实是启动一个事件,这个事件可以是Mono默认的事件,也可以是我们自己定义的;

而yield return 其实是返回这个事件的执行节点(通俗说,就是事件在哪暂停了);

具体关于Unity默认的中断协程的,将在文后进行总结.

4.关于Unity 自定义 协程事件

在C#脚本中,我们可以看到StartCorotine的参数是一个IEnumerator,而IEnumrator有什么用呢?通过阅读IEnumrator接口和查阅相关资料,并结合Unity的脚本生命周期:

我得出了一个大概的过程:根据在调用Update的上下文每次都会去调用yield return,而在yield return之前必执行我们协程逻辑函数里面的代码,所以,可以知道,我们开启协程之后,每帧都会调用我们的协程逻辑函数,但是它每帧都是从上一个协程中断节点(也就是yield return)处开始执行,直到逻辑函数执行完毕。

另外,有一点需要注意的是:StartCorotine的返回值是Coroutine,Coroutine继承了YieldInstruction,巧合的是yield return 后面的返回值,比如WaitForSceconds也继承了YieldInstruction,因此我猜测,yield return 后面的返回值对象应该和Corotine存在某种联系,而在我看过Unity官方文档之后,有一点点释然了:

事实上,这个YieldInstruction是IEnumrator的子类,姑且先这样认为.从文档中,可以了解到如果我们要写自定义协程事件,可以选择继承CustomYieldInstruction,也可以采用继承IEnumrator的方式都可以.也因此我认为CustomYieldInstruction是对IEnumrator的一层封装,单着仅仅是我个人猜测;这样,就可以理解为什么协程是基于迭代器的了;但是Corotine和yield return 存在什么联系,可能是Corotine需要IEnumrator来进行枚举,然而yield return 是提供IEnumrator进行枚举;或许是这种原因,如果说他们之间存在什么转换关系,可能就不得而知了。

5.Unity 中默认的 yield return 事件

yield WaitForFixedUpdate

yield null

yield WaitForSeconds

yield WWW

yield StartCorotine

yield WaitForEndOfFrame

上面这些其实很好理解,我觉得需要注意一下顺序即可.

yield WaitForFixedUpdate:Update之前

yield null:Update之后,下一帧执行

yield WaitForSeconds: 等待固定时间执行

yield StartCorotine: 等待另一个协程执行完毕

yield WaitForEndOfFrame:用于截屏

yield WaitUntil:等待委托Func返回为true时,执行下面的Code;在Update之后和LateUpdate之间调用.

using UnityEngine;

using System.Collections;

public class WaitUntilExample : MonoBehaviour

{

public int frame;

void Start()

{

StartCoroutine(Example());

}

IEnumerator Example()

{

Debug.Log("Waiting for princess to be rescued...");

yield return new WaitUntil(() => frame >= 10);

Debug.Log("Princess was rescued!");

}

void Update()

{

if (frame <= 10)

{

Debug.Log("Frame: " + frame);

frame++;

}

}

}

yield WaitWhile:等待委托Func返回为false时,执行下面的Code;在Update之后和LateUpdate之间调用.

using UnityEngine;

using System.Collections;

public class WaitWhileExample : MonoBehaviour

{

public int frame;

void Start()

{

StartCoroutine(Example());

}

IEnumerator Example()

{

Debug.Log("Waiting for prince/princess to rescue me...");

yield return new WaitWhile(() => frame < 10);

Debug.Log("Finally I have been rescued!");

}

void Update()

{

if (frame <= 10)

{

Debug.Log("Frame: " + frame);

frame++;

}

}

}

6.自定义yieldreturn事件

yield return 的返回值,我们可以根据自己需求来定义协程何时被继续执行;必须继承抽象类CustomYieldInstruction,实现KeepWaiting的Get方法.

using System.Collections;

using UnityEngine;

public class ExampleScript : MonoBehaviour

{

void Update()

{

if (Input.GetMouseButtonUp(0))

{

Debug.Log("Left mouse button up");

StartCoroutine(waitForMouseDown());

}

}

public IEnumerator waitForMouseDown()

{

yield return new WaitForMouseDown();

Debug.Log("Right mouse button pressed");

}

}

using UnityEngine;

public class WaitForMouseDown : CustomYieldInstruction

{

public override bool keepWaiting

{

get

{

return !Input.GetMouseButtonDown(1);

}

}

public WaitForMouseDown()

{

Debug.Log("Waiting for Mouse right button down");

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值