原文:https://www.cnblogs.com/xifarm/p/invoke.html
在Unity3D中,新建的腳本會默認繼承MonoBehaviour,其中Update函數會被引擎自動調度,如在我的電腦上,Update函數被調用的周期為0.012s。
那么Unity3D中,僅有通過Update函數來實現延時功能嗎? 還有無其他的實現呢?
怎么才能讓一個界面只顯示1秒之后 然后再執行其他的操作~
比如 游戲的勝利界面 只讓他顯示一秒 然后執行其他操作
答案是有的,下面就用過的幾種延時功能(定時器)一一列出來:
延時功能 |
是否繼承MonoBehaviour |
備注 |
Update函數 |
是 |
配合使用的函數: Timer.timer |
Invoke |
是 |
配合使用的函數: CancelInvoke InvokeRepeating IsInvoking |
Coroutine |
是 |
配合使用的函數: StartCoroutine StopAllCoroutines StopCoroutine |
DOTween (HOTween v2) |
否 |
|
VisionTimer.VP_Timer |
否 |
下面的幾個例子,我們在ShowA函數中,延時5s調用ShowB函數,通過代碼看看各個實現方法的異同。
為了方便,我僅截取部分關鍵代碼,是否繼承MonoBehaviour等自行添加即可。
-
Update函數 實現定時器
float m_timer = 0; void Update () { m_timer += Time.time; if (m_timer >= 5) { ShowB();
m_timer = 0; }
} private void ShowB() {
}
-
Update函數實現定時器,幾乎是學習Unity3D必修的功課。 但是,在實戰項目中需要維護m_timer這個變量,且從設計角度看,代碼寫得有些不整齊。
-
Invoke函數 實現定時器
GameController.Get().CancelInvoke();
GameController.Get().Invoke("ShowB", 5f);
private void ShowB()
{
game.ShowCardInTurn();
}
-
Invoke是MonoBehaviour提供的函數,可以延時調用函數,且可以通過CancelInvoke控制調度器的停止。 但是,Invoke的調用是在運行時生效的,對於ShowB函數,很容易導致在代碼審查階段被誤殺—函數刪除后,編譯不會報錯,你可能會誤認為這個函數是廢棄的函數。
-
Coroutine 協成 實現定時器
private IEnumerator ShowA() { yield return new WaitForSeconds(5);
ShowB(); } private void ShowB() {
}
使用協成的WaitForSeconds可以實現定時器,使用起來比較簡單。
-
DOTween 實現定時器
DOTween動畫插件,是在Unity 4.6時代,為了彌補UGUI無動畫腳本的先天不足而雲起的商業插件,當然雨松MoMO的《UGUI研究院之界面中使用DoTween(七)》對普及DOTWeen功不可沒。
private void ShowA() { GameObject go;
go.transform.DOMoveZ(0.1f, 5f) .OnComplete(new TweenCallback(ShowB)); } private void ShowB() {
}
DOTween的主要作用不是為了做延時調度用的,但是其帶有這個功能,且思想非常酷。
-
VP_Timer 實現定時器
vp_Timer.Handle Timer = new vp_Timer.Handle();
vp_Timer.In(5, new vp_Timer.Callback(() =>
{
Timer.Cancel();
ShowB();
}), Timer);
VP_Timer是某天下午,在網上搜索中,無意找到了,其簡潔的用法,着實讓人眼前一亮。 目前項目中,涉及的地方超過10處,極大的方便了延時功能的實現,非常不錯。 也為項目節約了大量的時間。
謝謝給我普及這個插件的博主啦: 《Unity時鍾定時器插件——Vision Timer源碼分析之一》。
上面的幾種方法,在實戰Unity3D項目中,均有所涉及,我本人用的比較多的是DOTWeen和VP_Timer,這2個不依賴繼承MonoBehaviour,相對比較靈活,且其是商業項目,封裝還是挺給力的。
如果大家還有其他實現方法,也歡迎分享,我們共同提高、進步。