Unity3D IEnumerator 做一個通用的定時器

在本文,你將學到如何使用迭代器做一個通用的定時器。

寫在前面:

寫一個通用的定時器,就是說定時結束后對調用的對象的某些狀態(tài)或值進行改變;
假如傳入一個bool量,定時到了返回他的取反值,此處立馬想到out 或者ref 來獲得方法回值,但是可惜迭代器不能有ref或out參數:


一般情況下迭代器里面不能使用out ref參數

解決思路:

不一定需要傳入bool,直接委托也很OK,下面簡單的代碼演示一下這個不錯的編程思路:

  • 這個類定義了定時器:
using System;
using System.Collections;
using UnityEngine;

public class cycle  {
    public static IEnumerator DelayT(float _time, Action _cmd)
    {
        yield return new WaitForSeconds(_time);
        _cmd.Invoke();
    }
    public static IEnumerator DelayTime(float _time, Action _cmd)
    {
        yield return new WaitForSeconds(_time);
        _cmd.Invoke();
//下面死循環(huán),測試手動退出協程
        while (true)
        {
            Debug.Log(111);
            yield return null;
        }
    }
}

  • 這個類演示調用定時器
using UnityEngine;

public class cycleget : MonoBehaviour
{
    private bool ifshow = false;
    [Range(0,10)]
    public float DelayTime = 1f;

    void Start()
    {
        Debug.Log(gameObject.name+"初始狀態(tài)字為false");
    }
    void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            StartCoroutine(cycle.DelayT(Mathf.Clamp(DelayTime,0,10),
                () => {
                    ifshow = !ifshow;
                    Debug.Log(gameObject.name+"時間到,狀態(tài)改變"+ifshow.ToString());
                }));
            Debug.Log(gameObject.name + "按下鼠標左鍵,狀態(tài)字為:" + ifshow.ToString());
        }
//一般來說,協程運行完畢自動退出,哪有沒有手動退出(或者人工干預停止協程)的方式?--答案是:有
//下面演示主動退出協程
 if (Input.GetMouseButtonDown(1))
 {
        Coroutine coroutine = null;//1.先聲明一個“Coroutine”的引用。
        coroutine=StartCoroutine(cycle.DelayTime(Mathf.Clamp(DelayTime,0,10), //2.這個引用指向我們開啟的那個協程
                () => {
                    ifshow = !ifshow;
                    Debug.Log(gameObject.name+"時間到,狀態(tài)改變"+ifshow.ToString());
        StopCoroutine(coroutine);//3.在我們需要完成的事情后結束這個引用。此時死循環(huán)打印“111”就得到了有效遏制,也就是人工干預停止了協程
                }));
            Debug.Log(gameObject.name + "按下鼠標左鍵,狀態(tài)字為:" + ifshow.ToString());
        }
    }
}

動畫演示:

動畫演示

Tips: 沒有加鎖,協程連續(xù)點擊連續(xù)執(zhí)行,這點需要注意;
解決重復點擊的問題可以用到數據結構,初步解決,思路可見下面的文章:
Unity3D 協程管理 - 簡書
但不建議封裝協程做定時器,筆者使用中發(fā)現會有安全問題哈。

Unity3D、IEnumerator 、通用定時器、Lambda、Action委托

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

  • 一:什么是協同程序? 答:在主線程運行時同時開啟另一段邏輯處理,來協助當前程序的執(zhí)行。換句話說,開啟協程就是開啟一...
    好怕怕閱讀 4,028評論 2 23
  • 一:什么是協同程序? 在主線程運行的同時開啟另一段邏輯處理,來協助當前程序的執(zhí)行,協程很像多線程,但是不是多線程,...
    胤醚貔貅閱讀 2,215評論 0 13
  • 更新:【面試題含答案】http://bbs.9ria.com/thread-288394-1-1.html 高頻問...
    好怕怕閱讀 5,081評論 3 53
  • Unity里面的協程好用,但總是在如何關閉指定協程,尤其是關閉帶參數的協程的問題上困惑不已。在本文,筆者帶你用最簡...
    雨落隨風閱讀 4,315評論 4 13
  • 談到鏈式編程,大家都會想到方法擴展,具象一些,就是想到DoTween,但是DoTween鏈式思想里面還有個很有意思...
    雨落隨風閱讀 4,296評論 11 18

友情鏈接更多精彩內容