在别的类中直接调用TimeManager.Instance.BeginTimer
using System;
using UnityEngine;
using System.Collections.Generic;
/// <summary>
/// 计时器管理器
/// </summary>
public class TimerManager : MonoBehaviour
{
//单例
private static TimerManager _instance;
public static TimerManager Instance
{
get
{
if (_instance == null)
{
GameObject go = new GameObject(typeof(TimerManager).ToString());
DontDestroyOnLoad(go);
_instance = go.AddComponent<TimerManager>();
}
return _instance;
}
}
public static bool isSync = true;//是否为同步执行
[HideInInspector] public List<TimerData> timerList = new List<TimerData>();//倒计时列表(存储所有的倒计时)
private float lastUpdateTime;//上一帧的时间(忽略时间缩放影响的真实时间)
private void Awake()
{
lastUpdateTime = Time.realtimeSinceStartup;
}
/// <summary>
/// 开始倒计时
/// </summary>
/// <param name="countdown">倒计时时间</param>
/// <param name="onFinish">回调</param>
/// <param name="timerName">计时器名称</param>
/// <param name="ignoreTimeScale">是否忽略时间缩放</param>
public void BeginTimer(float countdown, Action onFinish = null, string timerName = "", bool ignoreTimeScale = false)
{
TimerData timeData = new TimerData();
timeData.SetTimer(countdown, onFinish, timerName, ignoreTimeScale);
timerList.Add(timeData);
}
/// <summary>
/// 清除倒计时
/// </summary>
/// <param name="timerName">计时器名称</param>
public void ClearTimer(string timerName = "")
{
if (timerName == "")
{
timerList.Clear();
}
else
{
foreach (var timer in timerList)
{
if (timer.timerName == timerName)
{
timerList.Remove(timer);
return;
}
}
}
}
/// <summary>
/// 得到倒计时时间
/// </summary>
/// <param name="timerName">计时器名称</param>
public float GetTimer(string timerName)
{
foreach (var timer in timerList)
{
if (timer.timerName == timerName)
{
return timer.timer;
}
}
Debug.LogWarning("没有创建倒计时:" + timerName);
return -1;
}
private void Update()
{
//计算真实的时间增量
var realTime = Time.realtimeSinceStartup - lastUpdateTime;
lastUpdateTime = Time.realtimeSinceStartup;
//如果是同步则一直遍历倒计时列表并同步计算
if (isSync)
{
for (int i = 0; i < timerList.Count; i++)
{
if (timerList[i] == null)
{
break;
}
timerList[i].UpdateTimer(timerList[i].ignoreTimeScale ? realTime : Time.deltaTime);
if (timerList[i].isFinish)
{
timerList.RemoveAt(i);
i--;
}
}
}
//如果是异步则只对列表中的第一个倒计时进行计算
else
{
if (timerList.Count == 0 || timerList[0] == null)
{
return;
}
timerList[0].UpdateTimer(timerList[0].ignoreTimeScale ? realTime : Time.deltaTime);
if (timerList[0].isFinish)
{
timerList.RemoveAt(0);
}
}
}
}
/// <summary>
/// 每一个计时器的数据类
/// </summary>
public class TimerData
{
public float timer;//计时器
public bool isFinish;//本次倒计时是否完成
private Action onFinish;//回调
public string timerName;//计时器名称
public bool ignoreTimeScale;//是否忽略时间缩放
/// <summary>
/// 设置计时器
/// </summary>
/// <param name="countdown">倒计时时间</param>
/// <param name="callback">回调</param>
/// <param name="timerName">计时器名称</param>
/// <param name="ignoreTimeScale">是否忽略时间缩放</param>
public void SetTimer(float countdown, Action onFinish, string timerName, bool ignoreTimeScale)
{
timer = countdown;
this.onFinish = onFinish;
this.timerName = timerName;
this.ignoreTimeScale = ignoreTimeScale;
}
/// <summary>
/// 更新计时器
/// </summary>
/// <param name="deltaTime">增量时间</param>
public void UpdateTimer(float deltaTime)
{
timer -= deltaTime;
if (timer <= 0)
{
isFinish = true;
onFinish?.Invoke();
}
}
}