Unity3D日常开发】Unity3D中实现计时器工具类-正计时、倒计时、暂停计时、加速计时

网友投稿 1062 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

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

【Unity3D日常开发】Unity3D中实现计时器工具类-正计时、倒计时、暂停计时、加速计时

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小时内删除侵权内容。

上一篇:MySQL与PostgreSQL比较 哪个数据库更好
下一篇:【RecyclerView】 十一、RecyclerView 数据更新 ( 删除单条数据 | 批量删除数据 )
相关文章