Unity基礎-協程

Unity基礎-協程

四、協程

概述

協程(Coroutine),本質上并不是多線程,而是在當前線程中將代碼分時執行,不卡主線程。可以理解為,協程會把可能使主線程卡頓的程序分時分布進行。
協程通常用來:加載場景,異步加載文件,異步下載文件,批量創建物體防止卡頓。

協程與線程的區別

  • 新開一個線程是獨立的一個管道,和主線程并行。Unity支持多線程,但是新開的線程無法訪問Unity中的任何東西,只能靠中間樞紐和Unity主線程聯絡。
  • 新開一個協程是在原線程之上開啟,進行邏輯分時分布執行。

協程的使用

協程可以分為兩部分:1.協程函數本體,2.協程調度器。
協程本體就是一個能夠中間暫停返回的函數。協程調度器是Unity內部實現的,會在對應的時機幫助我們繼續執行協程函數。Unity只實現了協程調度的部分。
協同函數返回值必須是IEnumerator類型或者繼承他的類型。

// 聲明協程
IEnumerator MyCoroutineExample()
{print("111");yield return new WaitForSeconds(2);print("222");
}// 啟動協程
StartCoroutine(MyCoroutineExample());// 關閉全部協程
StopAllCoroutines(); // 關閉特定協程
Coroutine co1 = StartCoroutine(MyCoroutineExample());
StopCoroutine(co1);

協程函數本體與C#迭代器

協程的本體本質上就是一個C#迭代器的方法。
C# 迭代器(Iterator)是一種特殊的方法或 get 訪問器,允許你通過 yield return 語句逐步返回集合中的每個元素,而無需構建整個集合。它使得遍歷自定義集合類型變得非常簡單和高效。
IEnumerableIEnumerable<T> 接口的作用是使一個類型能夠被 foreach 語句遍歷。簡單來說,只要一個類型實現了 IEnumerable (或 IEnumerable<T>),你就可以在 foreach 循環中使用它。

如果我們不通過Unity中給的開啟協程的方法開啟協程,Unity的協程調度器就不會幫我們管理協程函數。但是我們可以自己執行迭代器函數內容。
繼承MonoBehavior后,開啟協程,相當于把一個協程函數放入Unity的協程調度器中幫助我們管理進行執行,具體的 yield return 后面的規則也是Unity實現定義好的。

yield return 的含義和類型

yield return 語句是協程的核心,它控制協程的暫停和恢復時機,并可以返回不同類型的對象以實現不同的等待邏輯。

  1. 下一幀執行

    • yield return 數字; (通常 yield return 0; 或其他數字,但通常用 null)
    • yield return null;
    • UpdateLateUpdate 之間執行。
  2. 等待指定秒后執行

    • yield return new WaitForSeconds(秒);
    • UpdateLateUpdate 之間執行。
  3. 等待下一個固定物理幀更新時執行

    • yield return new WaitForFixedUpdate();
    • FixedUpdate 和碰撞檢測相關函數之后執行。
  4. 等待攝像機和 GUI 渲染完成后執行

    • yield return new WaitForEndOfFrame();
    • LateUpdate 之后的渲染相關處理完畢后執行。
  5. 一些特殊類型的對象

    • 比如異步加載相關函數返回的對象(AsyncOperation)。
    • 通常在異步加載資源、異步加載場景、網絡加載時使用。
    • 一般在 UpdateLateUpdate 之間執行。
  6. 跳出協程

    • yield break;:用于提前終止協程的執行。

協程應用示例:計時器與大量對象生成

習題要求
  1. 利用協程制作一個簡單的秒表計時器,每秒在控制臺打印當前秒數。
  2. 使用協程在場景中隨機位置生成100000個立方體,確保在生成過程中不會出現明顯的卡頓,這可以通過在適當的時機使用 yield return null; 實現。
代碼實現
點擊展開/折疊 協程實現代碼
using System.Collections;
using UnityEngine;
using Random = UnityEngine.Random; // 明確指定Random命名空間,避免和System.Random沖突public class CoroutineExamples : MonoBehaviour
{int time = 0;// 啟動協程void Start(){StartCoroutine(MyTimerCoroutine()); // 更名為MyTimerCoroutineStartCoroutine(CreateManyCubesCoroutine()); // 更名為CreateManyCubesCoroutine}// 計時器協程IEnumerator MyTimerCoroutine(){while (true){print("秒" + time);time++;yield return new WaitForSeconds(1);}}// 生成大量立方體協程IEnumerator CreateManyCubesCoroutine(){for (int i = 0; i < 100000; i++){GameObject obj = GameObject.CreatePrimitive(PrimitiveType.Cube);obj.transform.position = new Vector3(Random.Range(-100, 100), Random.Range(-100, 100), Random.Range(-100, 100));if (i % 1000 == 0) // 每生成1000個立方體暫停一幀,避免卡頓{yield return null;}}}
}

總結

你可以簡化理解迭代器函數:C# 看到迭代器函數和 yield return 語法糖,就會把原本是一個的函數變成"幾部分"。我們可以通過迭代器從上到下遍歷這"幾部分"進行執行,就達到了將一個函數中的邏輯分時執行的目的。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/86720.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/86720.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/86720.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

UniApp組件封裝,2025年最新HarmonyOS鴻蒙模塊化開發項目式教程

一、環境配置與前置條件 ?開發工具要求? HBuilderX 4.64&#xff08;鴻蒙插件已預裝&#xff09;DevEco Studio 5.0.3.400&#xff08;真機調試必備&#xff09;鴻蒙離線SDK&#xff08;通過HBuilderX導入&#xff0c;每個項目獨立配置&#xff09; ?項目初始化 # 創建Vu…

C++ 精簡知識點

目錄 一、核心語法 1.指針VS引用 2. 類與對象&#xff08;必寫代碼&#xff09; 3. 繼承與多態&#xff08;必寫代碼&#xff09; 4. 模板&#xff08;必寫代碼&#xff09; 5.智能指針 6. 異常處理&#xff08;必寫結構&#xff09; 二、簡答題速記 三、考試應急策略 一…

7.Vue的compute計算屬性

3.8. 【computed】 作用&#xff1a;根據已有數據計算出新數據&#xff08;和Vue2中的computed作用一致&#xff09;。 <template><div class"person">姓&#xff1a;<input type"text" v-model"firstName"> <br>名&am…

在VSCode中借助AI豐富C++Qt應用程序

隨著國內外各類自動化編程助手的普及&#xff0c;作為傳統桌面C開發者&#xff0c;也要及時地用上這樣強大的工具。考慮到網速問題&#xff0c;國外的服務時斷時續&#xff0c;還是傾向于使用一些國產的大語言模型助手。我們今天就來看看在VSCode下使用大語言模型輔助Qt開發。 …

Java八股文——JVM「內存模型篇」

JVM的內存模型介紹一下 面試官您好&#xff0c;您問的“JVM內存模型”&#xff0c;這是一個非常核心的問題。在Java技術體系中&#xff0c;這個術語通常可能指代兩個不同的概念&#xff1a;一個是JVM的運行時數據區&#xff0c;另一個是Java內存模型&#xff08;JMM&#xff0…

RabbitMQ 高可用與可靠性保障實現

RabbitMQ 高可用與可靠性保障實現詳解 一、高可用架構設計1.1 集群部署模式1.2 鏡像隊列&#xff08;Mirrored Queue&#xff09; 二、可靠性保障機制2.1 消息持久化2.2 確認機制&#xff08;Confirm & Ack&#xff09;2.3 死信隊列&#xff08;DLX&#xff09; 三、容災與…

12.7Swing控件6 JList

在 Java Swing 中&#xff0c;列表框&#xff08;JList&#xff09;是用于顯示一組選項的組件&#xff0c;用戶可以從中選擇一個或多個項目。以下是關于 Swing 列表框的詳細介紹&#xff1a; 1. 基本概念與用途 作用&#xff1a;以垂直列表形式展示選項&#xff0c;支持單選或…

C++: condition_variable: wait_for -> unlock_wait_for_lock?

作為C++的初學者,面臨的一個很大的問題,就是很多的概念并不是可以通過名稱直觀的預知它要完成的細節,比如這里的condition_variable的wait_for。C++的設計意圖好像是,我告訴你這樣用,你只要這樣做就行,又簡單還實用!而且需要記住的規則量又大的驚人。最后看起來,更像是…

HTML版英語學習系統

HTML版英語學習系統 這是一個完全免費、無需安裝、功能完整的英語學習工具&#xff0c;使用HTML CSS JavaScript實現。 功能 文本朗讀練習 - 輸入英文文章&#xff0c;系統朗讀幫助練習聽力和發音&#xff0c;適合跟讀練習&#xff0c;模仿學習&#xff1b;實時詞典查詢 - 雙…

【JUC面試篇】Java并發編程高頻八股——線程與多線程

目錄 1. 什么是進程和線程&#xff1f;有什么區別和聯系&#xff1f; 2. Java的線程和操作系統的線程有什么區別&#xff1f; 3. 線程的創建方式有哪些? 4. 如何啟動和停止線程&#xff1f; 5. Java線程的狀態模型&#xff08;有哪些狀態&#xff09;&#xff1f; 6. 調用…

LSTM-SVM多變量時序預測(Matlab完整源碼和數據)

LSTM-SVM多變量時序預測&#xff08;Matlab完整源碼和數據&#xff09; 目錄 LSTM-SVM多變量時序預測&#xff08;Matlab完整源碼和數據&#xff09;效果一覽基本介紹程序設計參考資料 效果一覽 基本介紹 代碼主要功能 該代碼實現了一個LSTM-SVM多變量時序預測模型&#xff0c…

ES6——數組擴展之Set數組

在ES6&#xff08;ECMAScript 2015&#xff09;中&#xff0c;JavaScript的Set對象提供了一種存儲任何值唯一性的方式&#xff0c;類似于數組但又不需要索引訪問。這對于需要確保元素唯一性的場景非常有用。Set對象本身并不直接提供數組那樣的方法來操作數據&#xff08;例如ma…

日志收集工具-logstash

提示&#xff1a;Windows 環境下 安裝部署 logstash 采集日志文件 文章目錄 一、下載二、解壓部署三、常用插件四、常用配置 Logstash 服務器數據處理管道&#xff0c;能夠從多個來源采集數據&#xff0c;轉換數據&#xff0c;然后將數據發送到您最喜歡的存儲庫中。Logstash 沒…

6個月Python學習計劃 Day 21 - Python 學習前三周回顧總結

? 第一周&#xff1a;基礎入門與流程控制&#xff08;Day 1 - 7&#xff09; “打地基”的一周&#xff0c;我們走完了從變量、輸入輸出、判斷、循環到第一個小型系統的完整鏈路。 &#x1f4d8; 學習重點&#xff1a; Python 基礎語法&#xff1a;變量類型、字符串格式化、注…

Spring Boot SQL數據庫功能詳解

Spring Boot自動配置與數據源管理 數據源自動配置機制 當在Spring Boot項目中添加數據庫驅動依賴&#xff08;如org.postgresql:postgresql&#xff09;后&#xff0c;應用啟動時自動配置系統會嘗試創建DataSource實現。開發者只需提供基礎連接信息&#xff1a; 數據庫URL格…

java每日精進 6.11【消息隊列】

1.內存級Spring_Event 1.1 控制器層&#xff1a;StringTextController /*** 字符串文本管理控制器* 提供通過消息隊列異步獲取文本信息的接口*/ RestController RequestMapping("/api/string-text") public class StringTextController {Resourceprivate StringTex…

【凌智視覺模塊】rv1106 部署 ppocrv4 檢測模型 rknn 推理

PP-OCRv4 文本框檢測 1. 模型介紹 如有需要可以前往我們的倉庫進行查看 凌智視覺模塊 PP-OCRv4在PP-OCRv3的基礎上進一步升級。整體的框架圖保持了與PP-OCRv3相同的pipeline&#xff0c;針對檢測模型和識別模型進行了數據、網絡結構、訓練策略等多個模塊的優化。 從算法改…

uniapp Vue2 獲取電量的獨家方法:繞過官方插件限制

在使用 uniapp 進行跨平臺應用開發時&#xff0c;獲取設備電量信息是一個常見的需求。然而&#xff0c;uniapp 官方提供的uni.getBatteryInfo方法存在一定的局限性&#xff0c;它不僅需要下載插件&#xff0c;而且目前僅支持 Vue3&#xff0c;這讓使用 Vue2 進行開發的開發者陷…

Go語言中的if else控制語句

if else是Go語言中最基礎也最常用的條件控制語句&#xff0c;用于根據條件執行不同的代碼塊。下面我將詳細介紹Go語言中if else的各種用法和特性。 1. 基本語法 1.1. 最簡單的if語句 if 條件表達式 {// 條件為true時執行的代碼 } 示例&#xff1a; if x > 10 {fmt.Prin…

[Spring]-AOP

AOP場景 AOP: Aspect Oriented Programming (面向切面編程) OOP: Object Oriented Programming (面向對象編程) 場景設計 設計: 編寫一個計算器接口和實現類&#xff0c;提供加減乘除四則運算 需求: 在加減乘除運算的時候需要記錄操作日志(運算前參數、運算后結果)實現方案:…