亚洲 国产精品 日韩-亚洲 激情-亚洲 欧美 91-亚洲 欧美 成人日韩-青青青草视频在线观看-青青青草影院

千鋒教育-做有情懷、有良心、有品質的職業(yè)教育機構

手機站
千鋒教育

千鋒學習站 | 隨時隨地免費學

千鋒教育

掃一掃進入千鋒手機站

領取全套視頻
千鋒教育

關注千鋒學習站小程序
隨時隨地免費學習課程

當前位置:首頁  >  技術干貨  > 一節(jié)課徹底掌握Unity中協程的用法

一節(jié)課徹底掌握Unity中協程的用法

來源:千鋒教育
發(fā)布人:syq
時間: 2022-06-08 13:57:00 1654667820

  文章目錄

  一、前言

  二、學習使用協程

  1.首先定義多個定時器,去實現游戲中的邏輯...

  2.案例演示

  3.開啟和終止協程

  4.協程的返回值

  5.案例應用

  三、總結

  前言

  協程在Unity開發(fā)中非常重要,但注意:協程跟多線程沒有任何關系,不要將兩者混為一談,接下來就跟大家分享一下我對協程的理解及用法!

Unity中協程的用法

  一、協程是什么?

  協程是一段在主線程中執(zhí)行的代碼邏輯,協程不是多線程。Unity的協程在每幀結束后去檢測yiled的條件是否滿足。

  二、學習使用協程

  1.首先定義多個定時器,去實現游戲中的邏輯...

  代碼如下:

  float timer1 = 3f;

  float timer2 = 5f;

  float timer3 = 8f;

  void Update()

    {

        timer1 -= Time.deltaTime;

        if (timer1 <= 0)

        {

            Debug.Log("3s過后...");

            timer1 = 3f;

        }

    }

  相信大家都寫過類似代碼,這種代碼如果項目中需要多個定時器時,會顯得非常臃腫,并且我們經常忘記做一件事情,比如忘記充值定時器...

  我們都學過循環(huán),for循環(huán)中是將變量i定義為局部變量,封裝成一個代碼塊,那我們是否可以將定時器也封裝成一個代碼塊呢?如果可以的話,那么代碼應該是這樣的:

 for (float timer = 3; timer >= 0; timer -= Time.deltaTime)

        {

            

        }

  現在每一個計時器變量都成為for循環(huán)的一部分了,這看上去好多了,而且我不需要去單獨設置每一個迭代變量。 但是這段代碼放在哪里去執(zhí)行呢?start?update?顯然都不可以,所以恰好協程可以做到這一點。我們回顧一下協程的概念:

  為了能在連續(xù)的多幀中(在這個例子中,3秒鐘等同于很多幀)調用該方法,Unity必須通過某種方式來存儲這個方法的狀態(tài),

  -這是通過IEnumerator 中使用yield return語句得到的返回值,當你“yield”一個方法時,你相當于說了,“現在暫停這個方法,

  -然后在下一幀中從這里繼續(xù)執(zhí)行!”。

  注意:用0或者null來yield的意思是告訴協程等待下一幀,直到繼續(xù)執(zhí)行為止。

  當然,同樣的你可以繼續(xù)yield其他協程,我會在下一個教程中講到這些。

  代碼如下:

    IEnumerator CountDown(){

        for (float timer = 3; timer >= 0; timer -= Time.deltaTime)

        {

            yield return 0;//現在停止這個方法,然后在下一幀中從這里繼續(xù)執(zhí)行!

        }

        Debug.Log("3s以后...");

    }

  2.案例演示

  /*

  * 接下來通過實例

  * 1.實現打印5次--我要學游戲開發(fā)!

  * 2.實現將這5次輸出分到每一幀里去實現:每幀打印1次,共打印5次!

  * 3.每一幀輸出“我要學游戲開發(fā)!”,無限循環(huán)。。。

  通過在一個while循環(huán)中使用yield,你可以得到一個無限循環(huán)的協程,這幾乎就跟一個Update()循環(huán)等同。。。

  */

  2.代碼如下:

  IEnumerator SayHello5Times()

    {

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

        {

            Debug.Log("我要學游戲開發(fā)!");

            yield return 0;

        }

  3.類似Update,代碼如下:

 IEnumerator SayHello5Times()

 {

      while (true)

        {

            //1.輸出結果

            Debug.Log("我要學游戲開發(fā)!");

            //2.等待下一幀

            yield return 0;

        }

  //1.輸出結果

  Debug.Log("我要學游戲開發(fā)!");

  //2.等待下一幀

  //3. 這里永遠沒有機會執(zhí)行

  }

  但是跟Update()不一樣的是,你可以在協程中做一些更有趣的事:

  接下來做一個定時器 每隔幾秒完成某一件事

    IEnumerator CountSeconds()

    {

        int seconds = 0;

        while (true)

        {

            for (float timer = 0; timer < 1; timer += Time.deltaTime)

            {

                yield return 0;

            }

            seconds++;

            Debug.Log("自協程啟動以來已經過了"+ seconds+"秒");

        }

    }

  這個方法突出了協程一個非常酷的地方:方法的狀態(tài)被存儲了,這使得方法中定義的這些變量都會保存它們的值,即使是在不同的幀中。還記得這個教程開始時那些煩人的計時器變量嗎?通過協程,我們再也不需要擔心它們了,只需要把變量直接放到方法里面!實際還有更優(yōu)雅的實現方式!稍后會跟大家講到。

  3.開啟和終止協程

  之前,我們已經學過了通過 StartCoroutine()方法來開始一個協程。

  如果我們想要終止所有的協程,可以通過StopAllCoroutines()方法來實現,

  注意,這只會終止在調用該方法的對象中開始的協程,對于其他的MonoBehavior類中運行的協程不起作用。

  那我們怎么終止其中的一個協程呢?在這個例子里,這是不能的,如果你想要終止某一個特定的協程,

  那么你必須得在開始協程的時候將它的方法名作為字符串,就像這樣:

  1、以字符串開啟/關閉,缺點:只能有一個參數

        StartCoroutine("FirstTimer");

        StopCoroutine("FirstTimer”);

  2、開啟帶有參數的協程的兩種方式:

        StartCoroutine(Sayhi("hi")) 

        StartCoroutine("Sayhi","hi")

  3、如何終止多個參數的協程呢?接受返回值

    Coroutine stopCor_2 = StartCoroutine(Cor_2());

    StopCoroutine(stopCor_2);

  4、StopAllCoroutines

  5、通知禁用或者銷毀方式

      gameObject.SetActive(false); 

      //通過銷毀游戲對象方式和禁用同效果

      //Destroy(gameobject)

  4.協程的返回值

  協程一旦被開啟后 總是試圖將方法內的代碼執(zhí)行完 之后停止

  1.在此之前,我們yield的時候總是用0(或者null),僅僅告訴程序在繼續(xù)執(zhí)行前等待下一幀。協程最強大的一個功能就是它們可以通過使用yield語句來相互嵌套。

  2.yield return new WaitForSeconds(n) 表示在n秒后執(zhí)行后面的代碼 但是會收到time.timescale 影響 ,如下代碼:

  //隔一定時間完成某件事

    IEnumerator SaySomeThings()

    {

        Debug.Log("協程開始執(zhí)行");

        yield return StartCoroutine(Wait(1.0f));

        Debug.Log("距離上一條消息已經過去1秒了");

        yield return StartCoroutine(Wait(2.5f));

        Debug.Log("距離上一條消息已經過去2.5秒了");

    }

  上述方法用了yield,但它并沒有用0或者null,而是用了Wait()來yield,這相當于是說,“不再繼續(xù)執(zhí)行本程序,直到Wait程序結束”。

  等待的方法還可以使用下面方式來實現:

    IEnumerator Wait(float duration)

    {

        for (float timer = 0; timer < duration; timer += Time.deltaTime)

            yield return 0;

    }

  3.在協程內 如果遇到yield return StartCoroutine(test) 剩余的代碼將在子協程執(zhí)行完畢后才能繼續(xù)執(zhí)行

  4.如果遇到 yield return new WaitForFixedUpdate 表示剩余代碼將在FixedUpdate 執(zhí)行完畢后執(zhí)行

  5.如果遇到 yield return WWW 等待一個網絡請求完成后繼續(xù)向下執(zhí)行

  6.如果遇到 yield return gameObject; 表示在gameobj不為空時向下執(zhí)行

  5.案例應用

  控制對象行為的例子

  在最后一個例子中,我們就來看看協程如何像創(chuàng)建方便的計時器一樣來控制對象行為。協程不僅僅可以使用計數的時間來yield,它還能很巧妙地利用任何條件。將它與嵌套結合使用,你會得到控制游戲對象狀態(tài)的最強大工具。運動到某一位置,對于下面這個簡單腳本組件,我們可以在Inspector面板中給targetPosition和moveSpeed變量賦值,程序運行的時候,該對象就會在協程的作用下,以我們給定的速度運動到給定的位置。

  代碼如下:

public Vector3 targetPosition;  

    public float moveSpeed;

    void Start1()

    {

        StartCoroutine(MoveToPosition(targetPosition));

    }

 

    IEnumerator MoveToPosition(Vector3 target)

    {

        while (transform.position != target)

        {

            transform.position = Vector3.MoveTowards(transform.position, target, moveSpeed * Time.deltaTime);

            yield return 0;

        }

    }

  這樣,這個程序并沒有通過一個計時器或者無限循環(huán),而是根據對象是否到達指定位置來yield。

  我們可以讓運動到某一位置的程序做更多,不僅僅是一個指定位置,我們還可以通過數組來給它賦值更多的位置,通過MoveToPosition() ,我們可以讓它在這些點之間持續(xù)運動。

  代碼如下:

 public Vector3[] path;  

 

    void Start2()

    {

        StartCoroutine(MoveOnPath(true));

    }

 

    IEnumerator MoveOnPath(bool loop)

    {

        do

        {

            foreach (var point in path)

                yield return StartCoroutine(MoveToPosition(point));

        }

        while (loop);

    }

  還可以加一個布爾變量,你可以控制在對象運動到最后一個點時是否要進行循環(huán)。

  課堂練習:嘗試讓物體在某個點停留3s

  如果把Wait()程序加進來,這樣就能讓我們的對象在某個點就可以選擇是否暫停下來,就像一個正在巡邏的AI守衛(wèi)一樣,并且這種實現方式看起來非常優(yōu)雅!

  三、總結

  l 多個協程可以同時運行,它們會根據各自的啟動順序來更新;

  l 協程可以嵌套任意多層(在這個例子中我們只嵌套了一層);

  l 如果你想讓多個腳本訪問一個協程,那么你可以定義靜態(tài)的協程;

  l 協程不是多線程(盡管它們看上去是這樣的),它們運行在同一線程中,跟普通的腳本一樣;

  l 如果你的程序需要進行大量的計算,那么可以考慮在一個隨時間進行的協程中處理它們;

  l IEnumerator類型的方法不能帶ref或者out型的參數,但可以帶被傳遞的引用;

  l 協程有多種開啟和終止的方法,但是最好用哪種方式開啟,就是用哪種方式終止。

  更多關于“Unity”的問題,歡迎咨詢千鋒教育在線名師。千鋒教育多年辦學,課程大綱緊跟企業(yè)需求,更科學更嚴謹,每年培養(yǎng)泛IT人才近2萬人。不論你是零基礎還是想提升,都可以找到適合的班型,千鋒教育隨時歡迎你來試聽。

tags:
聲明:本站稿件版權均屬千鋒教育所有,未經許可不得擅自轉載。
10年以上業(yè)內強師集結,手把手帶你蛻變精英
請您保持通訊暢通,專屬學習老師24小時內將與您1V1溝通
免費領取
今日已有369人領取成功
劉同學 138****2860 剛剛成功領取
王同學 131****2015 剛剛成功領取
張同學 133****4652 剛剛成功領取
李同學 135****8607 剛剛成功領取
楊同學 132****5667 剛剛成功領取
岳同學 134****6652 剛剛成功領取
梁同學 157****2950 剛剛成功領取
劉同學 189****1015 剛剛成功領取
張同學 155****4678 剛剛成功領取
鄒同學 139****2907 剛剛成功領取
董同學 138****2867 剛剛成功領取
周同學 136****3602 剛剛成功領取
相關推薦HOT
人妻插B视频一区二区三区| 久久亚洲AV无码精品色午夜| 精品人妻人人做人人爽| 噜噜噜噜噜18禁私人影视| 欧美人与性动交XXⅩXX| 少妇厨房愉情理伦片BD在线观看| 无遮挡边摸边吃奶边做视频免费| 亚洲国产精品无码中文在线| 中日双语字幕高清在线观看| 成 人 网 站国产免费观看| 国产精品无码免费专区午夜| 久久变态刺激另类SM按摩| 欧美视频一区二区三区四区| 婷婷五月综合激情| 亚洲一区二区三区波多野结衣 | 国产精品久久久久久久久久免费 | 车上震动A级作爱视频| 国产精品乱码一区二区三| 久久久久久九九99精品| 日本老妇XXXXX免费| 亚洲AV中文乱码一区二| 97成人无码免费一区二区中文 | 国内永久免费CRM系统Z在线| 国内极度色诱视频网站| 国产精品免费看久久久| 旧番无码熟肉动漫在线观看| 日本乱妇乱子视频网站-百度| 小13箩利洗澡无码免费视频| 永久亚洲成A人片777777| 东欧av性无码高清| 久久精品无码一区二区APP| 国产精品高潮呻吟爱久久AV无码| 久久99国产精品久久99小说 | 亚洲综合熟女久久久30P| らだ天堂中文在线| 国内少妇人妻丰满AV| 欧美激情在线播放| 五十路レンタのおばさん| 中文字幕日本乱码仑区在线| 国产精产国品一二三产区区别| 久久亚洲AV无码精品色午夜麻| 色婷婷AV一区二区三区浪潮 | 双人床上做剧烈运动可以吗| 一本到12不卡视频在线DVD| 富婆推油偷高潮叫嗷嗷叫| 久久婷婷五月综合国产| 铜铜铜铜铜铜铜铜好痛好深色板| 影音先锋2020色资源网| 国产精品99久久久久久人| 男女一起差差差差差| 亚洲 熟 图片 小说 乱 妇| IJZZIJZZIJ亚洲大全| 极品少妇被猛的白浆直喷白浆| 人妻少妇乱子伦无码专区| 亚洲色成人网站WWW永久| 亚洲人妻AAA网站| 国产成人亚洲综合精品| 女人被躁到高潮嗷嗷叫游戏| 亚洲AV无码一区二区三区性色| 被公牛日到了高潮| 久久亚洲AV午夜福利精品一区二| 图片区小说区AV区| JIZZJIZZ亚洲日本少妇| 久久精品露脸对白国产| 无遮挡粉嫩小泬久久久久久久久| AV一区二区三区人妻少妇| 精品人妻AV无码一区二区三区| 色五月激情中文字幕| 51精产国品一二三产区| 娇妻被交换粗又大又硬视频| 四虎国产精品成人影院| 99国产精品久久99久久久| 久久99精品久久久大学生| 无码精品人妻一区二区三区免费看 | 日产精品一二三区| 中国少妇BBWBBW| 黄 色 视 频 在 线 免费观| 少妇被CAO高潮呻吟声| 97久久香蕉国产线看观看| 精品伊人久久大线蕉色首页| 无遮挡十八禁污污网站免费| 成人免费乱码大片A毛片| 免费看人妻丰满熟妇AV无码片| 亚洲VA国产VA天堂VA久久| 国产丶欧美丶日本不卡视频| 日本VA欧美VA欧美VA精品| 2021国内精品久久久久免费 | 亚洲午夜成人精品无码色欲| 国产欧美日韩精品丝袜高跟鞋| 日文文本乱码高清| CHINESETUBE国产在线| 老赵抱着媛媛在厨房做| 亚洲欧美成人一区二区三区| 国产欧美在线观看不卡| 熟妇一区二区三区| 成人乱码一区二区三区四区| 欧美精品成人久久AV爱乃娜美| 一面膜上边一面膜下边日本 | 女人张开腿让男人桶爽的| 一区国产情侣宾馆射| 四虎永久在线精品国产馆V视影院| 无码一区二区三区老色鬼| 蜜桃传媒一区二区亚洲AV| 亚洲AV自慰白浆喷水网站少妇| 国产成人精品午夜福利APP色多| 欧美 亚洲 日本 成人| ZLJZLJZLJ中国人水多多| 韩国羞耻漫画免费 | JAVASCRIPT的成熟分类| 迷迷糊糊挺进岳身体| 中国VITAFUSION孕妇| 久久影院九九被窝爽爽| 亚洲最大成人综合网720P| 久久99精品久久水蜜桃| 亚洲欧洲成人A∨在线观看| 精品97国产免费人成视频| 亚洲V国产V天堂A无码二区| 国产亚洲日韩AV在线播放不卡| 无码人妻AⅤ一区二区| 国产极品粉嫩馒头一线天AV| 同性男男黄网站在线观看国外| 国产AV激情无码久久| 未满十八18禁止午夜免费网站| 国产成人综合亚洲AV| 五十路六十路七十路熟婆| 国产青草视频在线观看| 亚洲AV色香蕉一区二区三区蜜桃| 国产午夜成人精品视频APP| 亚洲AV成人片无码网站网8X| 国产午夜三级一区二区三 | 国产欧美在线观看不卡| 亚洲AV无码一区二区三区dv| 很黄很黄的曰批视频| 亚洲精品美女久久7777777| 久久AV秘 一区二区三区蜜桃| 亚洲中文字幕久在线| 毛茸茸性XXXX毛茸茸毛茸茸| 18禁止午夜福利体验区| 欧美性猛交一区二区三区精品| 扒开校花的粉嫩小泬| 上面一个摸下面一个手念什么 | 精品无码国产日韩制服丝袜| 亚洲日本高清成人AⅤ片| 榴莲草莓视频黄丝瓜芭乐秋葵| 在线观看免费视频| 欧美又粗又大XXXXBBBB疯| 大陆国语对白国产AV片| 无码OL丝袜高跟秘书在线观看不| 国产熟女一区视频在线播放| 亚洲精品无码久久久久苍井空| 久久午夜夜伦鲁鲁片免费无码影院| 中文字幕无码免费久久9一区9 | H罩杯大胸爆乳交在线观看| 搡老女人老妇女老熟女偷拍| 国产伦精品一区二区三区免费| 亚洲国产精品久久久久婷婷图片 | 日韩精品无码AV中文无码版| 国产精品久久午夜夜伦鲁鲁 | 精品人体无码一区二区三区| 在线观看亚洲区激情AV| 强伦姧人妻三上悠亚中文字幕 | 久久亚洲精品国产亚洲老地址| AAAA级少妇高潮大片在线观看 | 亚洲精品无码鲁网中文电影| 美女内射毛片在线看免费人动物| а√在线中文网新版地址在线| 天堂AV无码大芭蕉伊人AV孕妇| 好爽毛片一区二区三区四| 中文国产成人精品久久| 日本熟妇大屁股人妻| 国产午夜精品一区二区三区不卡 | 久久久久人妻一区精品色| JEΑL0USVUE成熟50M| 无码人妻久久一区二区三区不卡 | 亚洲人成自拍网站在线观看| 女人被男人吃奶到高潮| 粉嫩粉嫩一区性色AV片| 亚洲精品乱码久久久久久按摩| 妺妺窝人体色www在线下载人| 短篇公交车高H肉辣全集目录| 亚洲AV无码专区色爱天堂老鸭窝| 鲁丝片一区二区三区免费| 厨房里挺进岳丰满大屁股 | 99久久久国产精品免费牛牛| 天天做天天爱夜夜爽毛片毛片| 精品无码人妻一区二区三区不卡 | 国产成人艳妇AA视频在线| 亚洲影院丰满少妇中文字幕无码| 欧洲肉欲K8播放毛片| 国产一产二产三精华液| 607080岁奶奶| 无人区码一码二码三码网页| 麻豆国产蜜桃臀视频在线观看| 儿子耕了母亲荒废的田| 亚洲综合色婷婷在线观看| 日日碰日日摸夜夜爽无码| 久久精品国产亚洲AⅤ无码| 大又大又粗又硬又爽少妇毛片| 亚洲欧美日韩精品久久| 日韩精品无码免费专区网站 |