在学习一项新事物前,要先了解我们的需求是什么,为什么需要计时器。我在试图做ACT游戏demo时,想要给角色加上技能冷却CD,在CD时间内角色不能释放技能,CD后才可以。于是有了需求就开始制作计时器吧。
计时器主体脚本:
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
| using System; using UnityEngine;
public enum TimerWorkState { NONE, WORKERING, DONE }
public class GameTimer { private float _startTime; private bool _stop; private Action _action; public TimerWorkState _state;
public GameTimer() { ResetTimer(); }
/// <summary> /// 唤醒一个计时器 /// </summary> /// <param name="time">计时时长</param> /// <param name="task">任务</param> public void CallOut(float time, Action task) { _startTime = time; _action = task; _stop = false; _state = TimerWorkState.WORKERING; }
public void Working() { _startTime -= Time.deltaTime; if (_startTime < 0) { _action.Invoke(); _stop = true; _state = TimerWorkState.DONE; } } public TimerWorkState GetTimerState() => _state;
public void ResetTimer() { _startTime = 0f; _stop = true; _action = null; _state = TimerWorkState.NONE; } }
|
计时器管理器:
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
| using System; using System.Collections.Generic; using System.Threading; using UnityEngine; using UnityEngine.UIElements;
public class TimerManager : SingleMono<TimerManager> { private List<GameTimer> _activeTimers = new List<GameTimer>(); private Queue<GameTimer> _dormancyTimers = new Queue<GameTimer>(); [SerializeField] private int _howManyTimer; private void Awake() { InitTimer(_howManyTimer); }
private void Update() { TimerWork(); }
//初始化计时器 private void InitTimer(int timer) { for (int i = 0; i < timer; i++) { GameTimer timer1 = new GameTimer(); _dormancyTimers.Enqueue(timer1); } }
public void TryGetOneTimer(float time,Action action) { if(_dormancyTimers.Count == 0) { GameTimer timer = new GameTimer(); timer.CallOut(time, action); _activeTimers.Add(timer); } else { GameTimer timer = _dormancyTimers.Dequeue(); timer.CallOut(time, action); ; _activeTimers.Add(timer); } }
private void TimerWork() { if(_activeTimers.Count == 0) return; for (int i = 0; i < _activeTimers.Count; i++) { if(_activeTimers[i].GetTimerState() == TimerWorkState.WORKERING) { _activeTimers[i].Working(); } else { _dormancyTimers.Enqueue(_activeTimers[i]); _activeTimers[i].ResetTimer(); _activeTimers.Remove(_activeTimers[i]); } } } }
|