很多時候協(xié)程在Unity中扮演了非常關(guān)鍵角色。在本文,筆者將帶大家整合一個協(xié)程管理工具,常言道:好馬配好鞍嘛~
寫在前面
將一些很耗時的工作平攤到每一幀去處理,實現(xiàn)了“異步”操作,有效的避免了主線程的阻塞。協(xié)程雖好,但協(xié)程的生命周期API卻匱乏的緊。
前些時候筆者看了一個叫 TaskManager的協(xié)程管理工具,茅塞頓開之余發(fā)現(xiàn)其封裝還可精簡,于是便有了此文,權(quán)當(dāng)筆記。
核心思路
就是將目標(biāo)協(xié)程再封裝到一個如下的一個協(xié)程中并啟動之:
IEnumerator CallWrapper()
{
// 更多時候,用戶會在 Awake / Start 方法開啟 Task ,故而延遲一針避免 Task 里面調(diào)用的對象未來得及初始化
yield return null;
IEnumerator e = Coroutine;
while (Running)
{
if (Paused)
yield return null; //類比于汽車掛擋一樣,需要等紅燈時候就掛上空擋唄
else
{
if (e != null && e.MoveNext())
{
yield return e.Current;
}
else
{
Running = false;
}
}
}
Finish();
}
這樣(迭代器層面的)包裝一下,就能夠?qū)崿F(xiàn)協(xié)程的 暫停、手動/自動停止啦。
生命周期
- 如何提供一套優(yōu)雅的 API 來管理生命周期呢?
筆者整合的API如下:
task.Start() //協(xié)程的運行,推薦使用擴展方法 IEnumerator.Start() 方式接管協(xié)程的運行。
task.Stop(); //協(xié)程的手動干預(yù)導(dǎo)致的停止
task.Pause(); //暫停
task.Resume();//協(xié)程的恢復(fù)運行
協(xié)程的運行筆者使用了方法擴展,這樣使得迭代器 IEnumerator具備了 Start() 方法,啟動協(xié)程就更簡單啦.
事件回歸到 UnityEvent ,統(tǒng)一了 API 的使用風(fēng)格:
task.OnCompleted.AddListener(v => //第一種事件注冊方式
{
if (v) //可以通過返回值知道協(xié)程結(jié)束,以及結(jié)束是有誰主導(dǎo)的
{
Debug.Log("操作完成:用戶取消了操作!");
}
else
{
Debug.Log("操作完成!");
}
});
- 事件注冊提供 OnComplete 方法并返回 task對象自身 ,以期實現(xiàn)鏈?zhǔn)骄幊田L(fēng)格:
task.OnComplete(v => Debug.Log("喵嗚~ ---" + v)); //第二種事件注冊方式(鏈?zhǔn)剑?
動畫演示

CoroutineManager
解決的痛點:
- 更簡潔的協(xié)程開啟方式。
- 更完善的協(xié)程生命周期 API:Stop、Pause、Resume 。
- 協(xié)程執(zhí)行完畢回調(diào)。
- 面向迭代器的start方法擴展,任意參數(shù)的協(xié)程都是一個start能夠接管的。
擴展閱讀
寫到最后
本文代碼見Github:UniCoroutineManager
Demo 提供了協(xié)程管理的完整工作流模板,僅供參考,共同進(jìn)步。