using UnityEngine; using System.Collections; using System.Collections.Generic; using System; public class F3DTime : MonoBehaviour { public static F3DTime time; // Timer objects List timers; // Timer removal queue List removalPending; private int idCounter; /// /// Timer entity class /// class Timer { public int id; public bool isActive; public float rate; public int ticks; public int ticksElapsed; public float last; public Action callBack; public Timer(int id_, float rate_, int ticks_, Action callback_) { id = id_; rate = rate_ < 0 ? 0 : rate_; ticks = ticks_ < 0 ? 0 : ticks_; callBack = callback_; last = 0; ticksElapsed = 0; isActive = true; } public void Tick() { last += Time.deltaTime; if (isActive && last >= rate) { last = 0; ticksElapsed++; callBack.Invoke(); if (ticks > 0 && ticks == ticksElapsed) { isActive = false; F3DTime.time.RemoveTimer(id); } } } } /// /// Awake /// void Awake() { time = this; timers = new List(); removalPending = new List(); } /// /// Creates new timer /// /// Tick rate /// Callback method /// Time GUID public int AddTimer(float rate, Action callBack) { return AddTimer(rate, 0, callBack); } /// /// Creates new timer /// /// Tick rate /// Number of ticks before timer removal /// Callback method /// Timer GUID public int AddTimer(float rate, int ticks, Action callBack) { Timer newTimer = new Timer(++idCounter, rate, ticks, callBack); timers.Add(newTimer); return newTimer.id; } /// /// Removes timer /// /// Timer GUID public void RemoveTimer(int timerId) { removalPending.Add(timerId); } /// /// Timer removal queue handler /// void Remove() { if (removalPending.Count > 0) { foreach (int id in removalPending) for (int i = 0; i < timers.Count; i++) if (timers[i].id == id) { timers.RemoveAt(i); break; } removalPending.Clear(); } } /// /// Updates timers /// void Tick() { for (int i = 0; i < timers.Count; i++) timers[i].Tick(); } // Update is called once per frame void Update() { Remove(); Tick(); } }