【Unity】在Unity中封装计时器功能

简介

在Unity中封装计时器功能

常用方法

  • AlarmAfter(float second, Action callBack) 执行一次
    • second 等待时间
    • callBack 将要执行方法
  • AlarmRepeat(float delay, float repeatInterval, Action callBack) 循环执行
    • delay 第一次执行前延时时间
    • repeatInterval 重复间隔
    • callBack 将要执行方法
  • Stop(Clock clock) 停止某一计时器
  • Dispose() 停止全部计时器

详细代码

Clock

public class Clock{
Action onAlarm;
private readonly ClockType type;
private readonly float alarmTime1;
private readonly DateTime alarmTime2 = DateTime.Now;
private readonly bool repeat;//是否重复
private readonly float interval = 10;
private float nextAlarmSecond;
public bool IsStopped{ get; private set; }
public Clock(float time, Action callBack){
type = ClockType.UNITY_TIME_CLOCK;
alarmTime1 = time;
onAlarm = callBack;
}
public Clock(float time, float interval, Action callBack){
type = ClockType.UNITY_TIME_CLOCK;
alarmTime1 = time;
repeat = true;
this.interval = interval;
nextAlarmSecond = time + interval;
onAlarm = callBack;
}
public Clock(DateTime time, Action callBack){
type = ClockType.DATE_TIME_CLOCK;
alarmTime2 = time;
onAlarm = callBack;
}
public void Invoke(){
switch (type){
case ClockType.DATE_TIME_CLOCK:
if (DateTime.Now >= alarmTime2){
Alarm(true);
IsStopped = true;
}
break;
case ClockType.UNITY_TIME_CLOCK:
if (repeat){
if (Time.time >= nextAlarmSecond){
Alarm(false);
nextAlarmSecond += interval;
}
}
else{
if (Time.time >= alarmTime1){
Alarm(true);
IsStopped = true;
}
}
break;
}
}
public void Abandon(){
if (IsStopped){
return;
}
IsStopped = true;
onAlarm = null;
}
private void Alarm(bool once){
try{
onAlarm?.Invoke();
}
catch (Exception e){
IsStopped = true;
onAlarm = null;
Debug.LogWarning(e.ToString());
}
finally{
if (once){
onAlarm = null;
}
}
}
}
public enum ClockType{
DATE_TIME_CLOCK,
UNITY_TIME_CLOCK,
}

ClockUtil

public class ClockUtil : SingletonMonoBehaviour<ClockUtil> {
readonly List<Clock> clocks = new();
public Clock AlarmAt(DateTime dateTime, Action callBack) {
if (dateTime < DateTime.Now) {
Debug.LogWarning($"不合理的报警时间:dateTime-->{dateTime}");
return null;
}
var clock = new Clock(dateTime, callBack);
clocks.Add(clock);
return clock;
}
public Clock AlarmAfter(float second, Action callBack) {
if (second < 0f) {
Debug.LogWarning($"不合理的报警时间:second-->{second}");
return null;
}
var clock = new Clock(Time.time + second, callBack);
if (second == 0f) {
clock.Invoke();
return clock;
}
clocks.Add(clock);
return clock;
}
public Clock AlarmRepeat(float delay, float repeatInterval, Action callBack){
if (delay < 0f) {
Debug.LogWarning($"不合理的延迟时间:delay-->{delay}");
return null;
}
if (repeatInterval <= 0f) {
Debug.LogWarning($"不合理的重复间隔:repeatInterval-->{repeatInterval}");
return null;
}
var clock = new Clock(Time.time + delay, repeatInterval, callBack);
clocks.Add(clock);
return clock;
}
public void Stop(Clock clock) {
clock?.Abandon();
}
public void Dispose() {
foreach (var clock in clocks) {
clock.Abandon();
}
}
private void Update() {
for (var i = clocks.Count - 1; i >= 0; i--) {
var clock = clocks[i];
if (clock.IsStopped) {
clocks.RemoveAt(i);
} else {
clock.Invoke();
}
}
}
}
posted @   星空探险家  阅读(174)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 【.NET】调用本地 Deepseek 模型
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库
点击右上角即可分享
微信分享提示