Created
May 1, 2016 00:06
-
-
Save GeordieP/b955e392b222a27600ed023fdfdabc73 to your computer and use it in GitHub Desktop.
Performant, flexible, and re-usable timers for Unity3D projects utilizing C# events and delegates
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Written by Geordie Powers | |
https://github.com/GeordieP/ | |
https://gist.github.com/GeordieP/ | |
MIT License | |
*/ | |
/* | |
USAGE: | |
Create a one-shot timer named "myTimer" with duration 3 seconds, and | |
call a method (return type void) named "myTimer_onFinish" when finished | |
Timer myTimer = TimerManager.Instance.CreateTimerOneshot(3.0f); | |
myTimer.onFinish += myTimer_onFinish; | |
myTimer.Start(); | |
To create and start the timer immediately: | |
Timer myTimer = TimerManager.Instance.StartTimerOneshot(3.0f); | |
myTimer.onFinish += myTimer_onFinish; | |
Repeating timers: | |
Timer myTimer = TimerManager.Instance.CreateTimerRepeat(3.0f); | |
myTimer.onFinish += myTimer_onFinish; | |
myTimer.Start(); | |
myTimer.Stop(); // call to stop, and .Start() to start again | |
*/ | |
using UnityEngine; | |
using System.Collections.Generic; | |
public class TimerManager : PersistentUnitySingleton<TimerManager> { | |
private List<Timer> timers = new List<Timer>(); | |
void Update () { | |
if (timers.Count < 1) return; | |
for (int i = 0; i < timers.Count; i++) { | |
if (timers[i].running) { | |
timers[i].Update(Time.deltaTime); | |
if (timers[i].finished && timers[i].DeleteOnFinish) { | |
timers.RemoveAt(i); | |
i--; | |
} | |
} | |
} | |
} | |
// One shot timers will run until they fire, then stop executing and wait until they're started again | |
// Create a timer and return it | |
public Timer CreateTimerOneshot(float duration) { | |
Timer temp = new Timer(duration); | |
timers.Add(temp); | |
return temp; | |
} | |
// Create a timer, start it, and return it | |
public Timer StartTimerOneshot(float duration) { | |
Timer temp = new Timer(duration); | |
timers.Add(temp); | |
temp.Start(); | |
return temp; | |
} | |
// Temporary one shot timers are the same as one shot timers, but they'll get deleted after they fire once | |
// Create a timer and return it | |
public Timer CreateTimerTemporaryOneshot(float duration) { | |
Timer temp = new Timer(duration); | |
temp.DeleteOnFinish = true; | |
timers.Add(temp); | |
return temp; | |
} | |
// Create a timer, start it, and return it | |
public Timer StartTimerTemporaryOneshot(float duration) { | |
Timer temp = new Timer(duration); | |
temp.DeleteOnFinish = true; | |
timers.Add(temp); | |
temp.Start(); | |
return temp; | |
} | |
// Repeating timers work the exact same way except they don't set the finished and running | |
// flags once they complete, they'll just invoke their callback and run again | |
// Repeating timers won't stop until .Stop() is called | |
public Timer CreateTimerRepeat(float duration) { | |
Timer temp = new Timer(duration); | |
temp.Repeat = true; | |
timers.Add(temp); | |
return temp; | |
} | |
// Create a timer, start it, and return it | |
public Timer StartTimerRepeat(float duration) { | |
Timer temp = new Timer(duration); | |
temp.Repeat = true; | |
timers.Add(temp); | |
temp.Start(); | |
return temp; | |
} | |
} | |
public class Timer { | |
public float elapsed, duration; | |
public bool running, finished; | |
public delegate void FinishAction(); | |
public event FinishAction onFinish; | |
private bool deleteOnFinish; | |
public bool DeleteOnFinish { | |
get { return deleteOnFinish; } | |
set { deleteOnFinish = true; } | |
} | |
private bool repeat; | |
public bool Repeat { | |
get { return repeat; } | |
set { repeat = true; } | |
} | |
public Timer(float duration) { | |
elapsed = 0f; | |
running = false; | |
finished = false; | |
this.duration = duration; | |
} | |
public void Start() { | |
running = true; | |
} | |
public void Stop() { | |
running = false; | |
} | |
public void Update(float deltaTime) { | |
elapsed += deltaTime; | |
if (elapsed >= duration) Finish(); | |
} | |
public void Finish() { | |
onFinish(); | |
elapsed = 0f; | |
if (repeat) return; | |
finished = true; | |
running = false; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
By Michael Stevenson at http://redframe-game.com/blog/global-managers-with-generic-singletons/ | |
*/ | |
using UnityEngine; | |
public class PersistentUnitySingleton<T> : MonoBehaviour where T : Component { | |
private static T instance; | |
public static T Instance { | |
get { | |
if (instance == null) { | |
instance = FindObjectOfType<T>(); | |
if (instance == null) { | |
GameObject obj = new GameObject(); | |
obj.name = "PersistentSingleton_" + typeof(T).FullName; | |
// obj.hideFlags = HideFlags.HideAndDontSave; | |
instance = obj.AddComponent<T>(); | |
} | |
} | |
return instance; | |
} | |
} | |
public virtual void Awake() { | |
DontDestroyOnLoad(this.gameObject); | |
if (instance == null) { | |
instance = this as T; | |
} else { | |
Destroy(gameObject); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment