Unity3D日常開發】Unity3D中實現計時器工具類-正計時、倒計時、暫停計時、加速計時

      網友投稿 1342 2022-05-29

      推薦閱讀

      CSDN主頁

      GitHub開源地址

      Unity3D插件分享

      簡書地址

      我的個人博客

      QQ群:1040082875

      大家好,我是佛系工程師

      ☆恬靜的小魔龍☆

      ,不定時更新Unity開發技巧,覺得有用記得一鍵三連哦。

      一、前言

      最近要實現個小功能:計時器。

      計時器的用處很多,比如說在游戲開發中顯示技能CD、buff持續時間、控制眩暈等狀態的持續時間。

      計時器的主要功能有:

      在規定時間內倒計時

      顯示倒計時時間

      顯示正計時時間

      暫停、繼續

      時間速率影響

      獲取倒計時剩余時間

      倒計時結束的回調

      話說大樹底下好乘涼,在有大佬的代碼就是方便很多,找了一篇大佬寫好的代碼:

      鏈接:unity計時器功能的實現

      在實際使用中修改了一部分代碼,將更加便捷使用,將修改后的代碼分享給出來。

      二、實現計時器

      2-1、計時器實現

      新建腳本,命名為Timer.cs:

      using UnityEngine; public delegate void CompleteEvent(); public delegate void UpdateEvent(float t); public class Timer : MonoBehaviour { UpdateEvent updateEvent; CompleteEvent onCompleted; bool isLog = true;//是否打印消息 float timeTarget; // 計時時間/ float timeStart; // 開始計時時間/ float offsetTime; // 計時偏差/ bool isTimer; // 是否開始計時/ bool isDestory = true; // 計時結束后是否銷毀/ bool isEnd; // 計時是否結束/ bool isIgnoreTimeScale = true; // 是否忽略時間速率 bool isRepeate; //是否重復 float now; //當前時間 正計時 float downNow; //倒計時 bool isDownNow = false; //是否是倒計時 // 是否使用游戲的真實時間 不依賴游戲的時間速度 float TimeNow { get { return isIgnoreTimeScale ? Time.realtimeSinceStartup : Time.time; } } ///

      /// 創建計時器:名字 根據名字可以創建多個計時器對象 /// public static Timer createTimer(string gobjName = "Timer") { GameObject g = new GameObject(gobjName); Timer timer = g.AddComponent(); return timer; } /// /// 開始計時 /// /// 目標時間 /// 是否是倒計時 /// 完成回調函數 /// 計時器進程回調函數 /// 是否忽略時間倍數 /// 是否重復 /// 完成后是否銷毀 public void startTiming(float timeTarget, bool isDownNow = false, CompleteEvent onCompleted_ = null, UpdateEvent update = null, bool isIgnoreTimeScale = true, bool isRepeate = false, bool isDestory = true, float offsetTime = 0, bool isEnd = false, bool isTimer = true) { this.timeTarget = timeTarget; this.isIgnoreTimeScale = isIgnoreTimeScale; this.isRepeate = isRepeate; this.isDestory = isDestory; this.offsetTime = offsetTime; this.isEnd = isEnd; this.isTimer = isTimer; this.isDownNow = isDownNow; timeStart = TimeNow; if (onCompleted_ != null) onCompleted = onCompleted_; if (update != null) updateEvent = update; } void Update() { if (isTimer) { now = TimeNow - offsetTime - timeStart; downNow = timeTarget - now; if (updateEvent != null) { if (isDownNow) { updateEvent(downNow); } else { updateEvent(now); } } if (now > timeTarget) { if (onCompleted != null) onCompleted(); if (!isRepeate) destory(); else reStartTimer(); } } } /// /// 獲取剩余時間 /// /// public float GetTimeNow() { return Mathf.Clamp(timeTarget - now, 0, timeTarget); } /// /// 計時結束 /// public void destory() { isTimer = false; isEnd = true; if (isDestory) Destroy(gameObject); } float _pauseTime; /// /// 暫停計時 /// public void pauseTimer() { if (isEnd) { if (isLog) Debug.LogWarning("計時已經結束!"); } else { if (isTimer) { isTimer = false; _pauseTime = TimeNow; } } } /// /// 繼續計時 /// public void connitueTimer() { if (isEnd) { if (isLog) Debug.LogWarning("計時已經結束!請從新計時!"); } else { if (!isTimer) { offsetTime += (TimeNow - _pauseTime); isTimer = true; } } } /// /// 重新計時 /// public void reStartTimer() { timeStart = TimeNow; offsetTime = 0; } /// /// 更改目標時間 /// /// public void changeTargetTime(float time_) { timeTarget = time_; timeStart = TimeNow; } /// /// 游戲暫停調用 /// /// void OnApplicationPause(bool isPause_) { if (isPause_) { pauseTimer(); } else { connitueTimer(); } } }

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      16

      17

      18

      19

      20

      21

      22

      23

      24

      25

      26

      27

      28

      29

      30

      31

      32

      33

      34

      35

      36

      37

      38

      39

      40

      41

      42

      43

      44

      45

      46

      47

      48

      49

      50

      51

      52

      53

      54

      55

      56

      57

      58

      59

      60

      61

      62

      63

      64

      65

      66

      67

      68

      69

      70

      71

      72

      73

      74

      75

      76

      77

      78

      79

      80

      81

      82

      83

      84

      85

      86

      87

      88

      89

      90

      91

      92

      93

      94

      95

      96

      97

      98

      99

      100

      101

      102

      103

      104

      105

      106

      107

      108

      109

      110

      111

      112

      113

      114

      115

      116

      117

      118

      119

      120

      121

      122

      123

      124

      125

      126

      127

      128

      129

      130

      131

      132

      133

      134

      135

      136

      137

      138

      139

      140

      141

      142

      143

      144

      145

      146

      147

      【Unity3D日常開發】Unity3D中實現計時器工具類-正計時、倒計時、暫停計時、加速計時

      148

      149

      150

      151

      152

      153

      154

      155

      156

      157

      158

      159

      160

      161

      162

      163

      164

      165

      166

      167

      168

      169

      170

      171

      172

      173

      174

      175

      176

      177

      178

      179

      180

      181

      182

      183

      184

      185

      186

      187

      188

      189

      190

      191

      192

      193

      調用的計時器的腳本Test.cs:

      using UnityEngine; using System.Collections; using System; public class Test : MonoBehaviour { void Start() { // 創建計時器 Timer timer = Timer.createTimer("GameTime"); //開始計時 timer.startTiming(10, true, OnComplete, OnProcess); } // 計時結束的回調 void OnComplete() { Debug.Log("計時完成"); } // 計時器的進程 void OnProcess(float p) { Debug.Log(FormatTime(p)); } ///

      /// 格式化時間 /// /// 秒 /// public static string FormatTime(float seconds) { TimeSpan ts = new TimeSpan(0, 0, Convert.ToInt32(seconds)); string str = ""; if (ts.Hours > 0) { str = ts.Hours.ToString("00") + ":" + ts.Minutes.ToString("00") + ":" + ts.Seconds.ToString("00"); } if (ts.Hours == 0 && ts.Minutes > 0) { str = ts.Minutes.ToString("00") + ":" + ts.Seconds.ToString("00"); } if (ts.Hours == 0 && ts.Minutes == 0) { str = "00:" + ts.Seconds.ToString("00"); } return str; } }

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      16

      17

      18

      19

      20

      21

      22

      23

      24

      25

      26

      27

      28

      29

      30

      31

      32

      33

      34

      35

      36

      37

      38

      39

      40

      41

      42

      43

      44

      45

      46

      47

      48

      49

      50

      2-2、測試倒計時

      將Test.cs腳本附到場景中任意對象上,運行程序,測試倒計時:

      3-3、測試正計時

      修改代碼,測試正計時:

      void Start() { // 創建計時器 Timer timer = Timer.createTimer("GameTime"); //開始計時 timer.startTiming(10, false, OnComplete, OnProcess); }

      1

      2

      3

      4

      5

      6

      7

      運行結果:

      3-4、測試獲取剩余時間

      修改代碼:

      using UnityEngine; using System.Collections; using System; public class Test : MonoBehaviour { Timer timer; void Start() { // 創建計時器 timer = Timer.createTimer("GameTime"); //開始計時 timer.startTiming(10, true); } void Update() { Debug.Log(timer.GetTimeNow()); } }

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      16

      17

      18

      19

      20

      這次不使用回調函數,直接使用Update去獲取剩余時間,運行結果:

      3-5、測試暫停和繼續

      繼續修改代碼:

      using UnityEngine; using System.Collections; using System; public class Test : MonoBehaviour { Timer timer; void Start() { // 創建計時器 timer = Timer.createTimer("GameTime"); //開始計時 timer.startTiming(10, true, OnComplete, OnProcess); } void Update() { if (Input.GetKeyDown(KeyCode.W)) { Debug.Log("暫停"); timer.pauseTimer();//暫停 } if (Input.GetKeyDown(KeyCode.S)) { Debug.Log("繼續"); timer.connitueTimer();//繼續 } if (Input.GetKeyDown(KeyCode.A)) { Debug.Log("重新計時"); timer.reStartTimer();//重新計時 } if (Input.GetKeyDown(KeyCode.D)) { Debug.Log("更改目標時間:20"); timer.changeTargetTime(20);//更改目標時間 } } // 計時結束的回調 void OnComplete() { Debug.Log("計時完成"); } // 計時器的進程 void OnProcess(float p) { Debug.Log(FormatTime(p)); } ///

      /// 格式化時間 /// /// 秒 /// public static string FormatTime(float seconds) { TimeSpan ts = new TimeSpan(0, 0, Convert.ToInt32(seconds)); string str = ""; if (ts.Hours > 0) { str = ts.Hours.ToString("00") + ":" + ts.Minutes.ToString("00") + ":" + ts.Seconds.ToString("00"); } if (ts.Hours == 0 && ts.Minutes > 0) { str = ts.Minutes.ToString("00") + ":" + ts.Seconds.ToString("00"); } if (ts.Hours == 0 && ts.Minutes == 0) { str = "00:" + ts.Seconds.ToString("00"); } return str; } } } return str; } }

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      16

      17

      18

      19

      20

      21

      22

      23

      24

      25

      26

      27

      28

      29

      30

      31

      32

      33

      34

      35

      36

      37

      38

      39

      40

      41

      42

      43

      44

      45

      46

      47

      48

      49

      50

      51

      52

      53

      54

      55

      56

      57

      58

      59

      60

      61

      62

      63

      64

      65

      66

      67

      68

      69

      70

      71

      72

      73

      74

      75

      76

      77

      78

      運行程序:

      3-6、測試游戲加速

      修改代碼后:

      using UnityEngine; using System.Collections; using System; public class Test : MonoBehaviour { Timer timer; void Start() { Time.timeScale = 2;//游戲加速 // 創建計時器 timer = Timer.createTimer("GameTime"); //開始計時 timer.startTiming(60, true, OnComplete, OnProcess, false); } // 計時結束的回調 void OnComplete() { Debug.Log("計時完成"); } // 計時器的進程 void OnProcess(float p) { Debug.Log(FormatTime(p)); } ///

      /// 格式化時間 /// /// 秒 /// public static string FormatTime(float seconds) { TimeSpan ts = new TimeSpan(0, 0, Convert.ToInt32(seconds)); string str = ""; if (ts.Hours > 0) { str = ts.Hours.ToString("00") + ":" + ts.Minutes.ToString("00") + ":" + ts.Seconds.ToString("00"); } if (ts.Hours == 0 && ts.Minutes > 0) { str = ts.Minutes.ToString("00") + ":" + ts.Seconds.ToString("00"); } if (ts.Hours == 0 && ts.Minutes == 0) { str = "00:" + ts.Seconds.ToString("00"); } return str; } }

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      16

      17

      18

      19

      20

      21

      22

      23

      24

      25

      26

      27

      28

      29

      30

      31

      32

      33

      34

      35

      36

      37

      38

      39

      40

      41

      42

      43

      44

      45

      46

      47

      48

      49

      50

      51

      52

      運行程序,不忽略游戲加速:

      運行程序,忽略游戲加速:

      三、后記

      你的就是對博主的支持,有問題記得留言:

      博主主頁有聯系方式。

      博主還有跟多寶藏文章等待你的發掘哦:

      5G游戲 unity

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:Python系列:面向對象“類”之類成員
      下一篇:軟件就是敲代碼?一篇文章帶你了解軟件生存周期!
      相關文章
      爱情岛论坛网亚洲品质自拍| 亚洲人成网国产最新在线| 18禁亚洲深夜福利人口| 亚洲人成7777影视在线观看| 狠狠色伊人亚洲综合成人| 亚洲人成电影网站国产精品 | 国产成人无码综合亚洲日韩| 亚洲电影日韩精品 | 日本亚洲视频在线| 亚洲成a人片在线观看无码专区| 中文字幕亚洲激情| 亚洲无线观看国产精品| 久久亚洲国产午夜精品理论片| 好看的电影网站亚洲一区 | 亚洲色成人四虎在线观看| 久久乐国产综合亚洲精品| 亚洲日韩国产欧美一区二区三区| 亚洲AV成人影视在线观看 | 久久久久久a亚洲欧洲AV| 亚洲男人天堂av| 亚洲成人福利在线观看| 亚洲视频免费观看| 亚洲av成人一区二区三区| 亚洲人成无码网站在线观看| 亚洲一区二区三区成人网站| 理论亚洲区美一区二区三区| 亚洲精品色婷婷在线影院| 亚洲午夜久久久影院| 五月天网站亚洲小说| 亚洲国产高清视频在线观看| youjizz亚洲| 亚洲AV色欲色欲WWW| 亚洲精品久久久www| 精品亚洲永久免费精品| 亚洲尹人九九大色香蕉网站| 亚洲六月丁香六月婷婷蜜芽| 亚洲色成人WWW永久在线观看| www.亚洲色图| 亚洲精品~无码抽插| 日木av无码专区亚洲av毛片| 亚洲w码欧洲s码免费|