網站首頁 編程語言 正文
在Unity中,一般的方法都是順序執行的,一般的方法也都是在一幀中執行完畢的,當我們所寫的方法需要耗費一定時間時,便會出現幀率下降,畫面卡頓的現象。當我們調用一個方法想要讓一個物體緩慢消失時,除了在Update中執行相關操作外,Unity還提供了更加便利的方法,這便是協程。
在通常情況下,如果我們想要讓一個物體逐漸消失,我們希望方法可以一次調用便可在程序后續執行中實現我們想要的效果。
我們希望代碼可以寫成如下所示:
void Fade()
{
for (float f = 1f; f >= 0; f -= 0.1f)
{
Color c = renderer.material.color;
c.a = f;
renderer.material.color = c;
}
}
然而該方法在調用時將在一幀中執行完畢,無法實現預期的效果。如果將該方法改寫并放到Update函數中可實現我們預期的效果,但是還不夠優雅。
float time = 0f;
float fadeTime = 2f;
void Fade()
{
time += Time.dealttime;
Color c = renderer.material.color;
c.a = 1f - time/fadeTime;
renderer.material.color = c;
}
Unity中的協程方法通過yield這個特殊的屬性可以在任何位置、任意時刻暫停。也可以在指定的時間或事件后繼續執行,而不影響上一次執行的就結果,提供了極大地便利性和實用性。
協程在每次執行時都會新建一個(偽)新線程來執行,而不會影響主線程的執行情況。
正如上邊的方法,我們使用協程可以更加方便的實現我們想要的效果。
void Fade()
{
for (float f = 1f; f >= 0; f -= 0.1f)
{
Color c = renderer.material.color;
c.a = f;
renderer.material.color = c;
yield return null;//下一幀繼續執行for循環
yield return new WaitForSeconds(0.1f);//0.1秒后繼續執行for循環
}
}
我們通過StartCoroutine()函數來調用協程函數。
值得注意的是,協程并不會在Unity中開辟新的線程來執行,其執行仍然發生在主線程中。當我們有較為耗時的操作時,可以將該操作分散到幾幀或者幾秒內完成,而不用在一幀內等這個操作完成后再執行其他操作。
如我們需要執行一個循環:
IEnumerator CaculateResult()
{
for (int i = 0; i < 10000; i++)
{
//內部循環計算
//在這里的yield會讓改內部循環計算每幀執行一次,而不會等待10000次循環結束后再跳出
//yield return null;
}
//如果取消內部的yield操作,僅在for循環外邊寫yield操作,則會執行完10000次循環后再結束,相當于直接調用了一個函數,而非協程。
//yield return null;
}
調用協程的方法有兩種,分別是StartCoroutine(/這里直接調用方法,添加參數/),另一種是StartCoroutine(/這里填寫”字符串的方法名字”,方法參數/)。第一種方法的優勢在于可以調用多個參數的方法,后一種方法只能調用不含參數或只包含一個參數的協程方法。但是第一種方法不能通過StopCoroutine(/這里填寫”字符串的方法名”/)來結束協程,只能通過StopAllCoroutines來結束。后一種則可以通過StopCoroutine來結束對正在執行的協程的調用。
協程在實現過程中我們需要注意yield調用的時機,執行較為復雜的計算時,如果在時間上沒有嚴格的先后順序,我們可以每幀執行一次循環來完成計算,或者每幀執行指定次數的循環來防止在程序運行中出現的卡頓現象。
yield return的介紹:
yield return null; // 下一幀再執行后續代碼
yield return 0; //下一幀再執行后續代碼
yield return 6;//(任意數字) 下一幀再執行后續代碼
yield break; //直接結束該協程的后續操作
yield return asyncOperation;//等異步操作結束后再執行后續代碼
yield return StartCoroution(/*某個協程*/);//等待某個協程執行完畢后再執行后續代碼
yield return WWW();//等待WWW操作完成后再執行后續代碼
yield return new WaitForEndOfFrame();//等待幀結束,等待直到所有的攝像機和GUI被渲染完成后,在該幀顯示在屏幕之前執行
yield return new WaitForSeconds(0.3f);//等待0.3秒,一段指定的時間延遲之后繼續執行,在所有的Update函數完成調用的那一幀之后(這里的時間會受到Time.timeScale的影響);
yield return new WaitForSecondsRealtime(0.3f);//等待0.3秒,一段指定的時間延遲之后繼續執行,在所有的Update函數完成調用的那一幀之后(這里的時間不受到Time.timeScale的影響);
yield return WaitForFixedUpdate();//等待下一次FixedUpdate開始時再執行后續代碼
yield return new WaitUntil()//將協同執行直到 當輸入的參數(或者委托)為true的時候....如:yield return new WaitUntil(() => frame >= 10);
yield return new WaitWhile()//將協同執行直到 當輸入的參數(或者委托)為false的時候.... 如:yield return new WaitWhile(() => frame < 10);
當某一個腳本中的協程在執行過程中,如果我們將該腳本的enable設置為false,協程不會停止。只有將掛載該腳本的物體設置為SetActive(false)時才會停止。
Unity在調用StartCoroutine()后不會等待協程中的內容返回,會立即執行后續代碼。
雖然協程十分方便和靈活,但不當的使用會使程序產生無法預想的后果,請使用前慎重考慮。
原文鏈接:https://blog.csdn.net/beihuanlihe130/article/details/76098844
相關推薦
- 2022-04-02 nginx網頁緩存時間的配置過程_nginx
- 2022-09-30 Centos7?Shell編程之正則表達式、文本處理工具詳解_正則表達式
- 2022-10-16 Django完整增刪改查系統實例代碼_python
- 2022-10-03 go?Antlr重構腳本解釋器實現示例_Golang
- 2022-02-18 Ubuntu重啟后nvidia-smi命令報錯NVIDIA-SMI has failed becau
- 2022-08-07 Android?文件存儲系統原理_Android
- 2022-05-12 基于nginx反向代理獲取用戶真實Ip地址詳解_nginx
- 2022-04-01 mybatis if 并且判斷列表是否為空
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支