Tower Defense 复习第二篇

有关携程的学习

协程:协同程序,在主程序运行的同时开启另一端逻辑处理,来协同当前程序的执行
开启协同的两种方式
1.StartCoroutine(string methodName)
注意:
(1)参数是方法名,此方法可以包含一个参数
(2)形参方法可以有返回值
2.StartCoroutine(IEnumerator method)
注意:
(1)参数是方法名,方法中可以包含多个参数
(2)IEnumerator 类型的方法不能含有ref或者out类型的参数,但可以含有被传递的引用
(3)必须有返回值,且返回值类型为IEnumerator,返回值使用(yield return +表达式或者值,或者 yield break)语句

终止协程的两种方式:
StopCoroutine(string methodName),只能终止指定的协程
使用注意:
在程序中调用StopCoroutine()方法能终止以字符串形式启动的协程

也可以终止Coroutine类型的值

IEnumerator的返回值类型

yield:挂起,程序遇到yield关键字时会被挂起,暂停执行,等待条件满足时从当前位置继续执行

yield return 0 or yield return null:程序在下一帧中从当前位置继续执行

yield return 1,2,3,…: 程序等待1,2,3…帧之后从当前位置继续执行

yield return new WaitForSeconds(n):程序等待n秒后从当前位置继续执行

yield new WaitForEndOfFrame():在所有的渲染以及GUI程序执行完成后从当前位置继续执行

yield new WaitForFixedUpdate():所有脚本中的FixedUpdate()函数都被执行后从当前位置继续执行

yield return WWW:等待一个网络请求完成后从当前位置继续执行

yield return StartCoroutine():等待一个协程执行完成后从当前位置继续执行

yield break

如果使用yield break语句,将会导致协程的执行条件不被满足,不会从当前的位置继续执行程序,而是直接从当前位置跳出函数体,回到函数的根部

注意
协程不是线程,也不是异步执行的。协程和 MonoBehaviour 的 Update函数一样也是在MainThread中执行的。使用协程你不用考虑同步和锁的问题。

IEnumerator & Coroutine

协程其实就是一个IEnumerator(迭代器),IEnumerator 接口有两个方法 Current 和 MoveNext() ,前面介绍的 TaskManager 就是利用者两个方法对协程进行了管理,只有当MoveNext()返回 true时才可以访问 Current,否则会报错。迭代器方法运行到 yield return 语句时,会返回一个expression表达式并保留当前在代码中的位置。 当下次调用迭代器函数时执行从该位置重新启动。

Unity在每帧做的工作就是:调用 协程(迭代器)MoveNext() 方法,如果返回 true ,就从当前位置继续往下执行。

using System;  
using System.Collections.Generic;  
using System.Linq;  
using UnityEngine;  
using System.Collections;  
   
[RequireComponent(typeof(GUIText))]  
public class Hijack : MonoBehaviour {  
   
    //This will hold the counting up coroutine  
    IEnumerator _countUp;  
    //This will hold the counting down coroutine  
    IEnumerator _countDown;  
    //This is the coroutine we are currently  
    //hijacking  
    IEnumerator _current;  
   
    //A value that will be updated by the coroutine  
    //that is currently running  
    int value = 0;  
   
    void Start()  
    {  
        //Create our count up coroutine  
        _countUp = CountUp();  
        //Create our count down coroutine  
        _countDown = CountDown();  
        //Start our own coroutine for the hijack  
        StartCoroutine(DoHijack());  
    }  
   
    void Update()  
    {  
        //Show the current value on the screen  
        guiText.text = value.ToString();  
    }  
   
    void OnGUI()  
    {  
        //Switch between the different functions  
        if(GUILayout.Button("Switch functions"))  
        {  
            if(_current == _countUp)  
                _current = _countDown;  
            else  
                _current = _countUp;  
        }  
    }  
   
    IEnumerator DoHijack()  
    {  
        while(true)  
        {  
            //Check if we have a current coroutine and MoveNext on it if we do  
            if(_current != null && _current.MoveNext())  
            {  
                //Return whatever the coroutine yielded, so we will yield the  
                //same thing  
                yield return _current.Current;  
            }  
            else  
                //Otherwise wait for the next frame  
                yield return null;  
        }  
    }  
   
    IEnumerator CountUp()  
    {  
        //We have a local increment so the routines  
        //get independently faster depending on how  
        //long they have been active  
        float increment = 0;  
        while(true)  
        {  
            //Exit if the Q button is pressed  
            if(Input.GetKey(KeyCode.Q))  
                break;  
            increment+=Time.deltaTime;  
            value += Mathf.RoundToInt(increment);  
            yield return null;  
        }  
    }  
   
    IEnumerator CountDown()  
    {  
        float increment = 0f;  
        while(true)  
        {  
            if(Input.GetKey(KeyCode.Q))  
                break;  
            increment+=Time.deltaTime;  
            value -= Mathf.RoundToInt(increment);  
            //This coroutine returns a yield instruction  
            yield return new WaitForSeconds(0.1f);  
        }  
    }  
   
}  

资料参考Unity协程(Coroutine)原理深入剖析

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值