Skip to content

Instantly share code, notes, and snippets.

@123tris
Last active January 22, 2024 00:45
Show Gist options
  • Star 8 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save 123tris/4dc40e5909f2c79952dab04038a3c12d to your computer and use it in GitHub Desktop.
Save 123tris/4dc40e5909f2c79952dab04038a3c12d to your computer and use it in GitHub Desktop.
A unity script for easily delaying parts of your code
//----------- Example code -----------
float health = 5;
CooldownManager.Cooldown(2, () => health++); //Delay health increment by 2 seconds
CooldownManager.Cooldown(5, Shoot); //Invoke shoot in 5 seconds
void Shoot () { }
//If you dont want to use lambda's for functions with parameters you can overload the function like so:
CooldownManager.Cooldown(2, Damage, 5); //Calls Damage() function with damageValue 5 after 2 seconds have passed
void Damage(int damageValue) { }
//You can also use a string to toggle the same coroutine in different parts of code. (This is global)
//An example usage would be someting like an ability cooldown:
bool abilityOnCooldown = true;
float cooldownLength = 2;
//If this gets called multiple times before the cooldown could finish, the cooldown time will get reset without invoking the action
CooldownManager.Cooldown(cooldownLength, () => abilityOnCooldown = false, "AbilityCooldown");
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// https://gist.github.com/karljj1/9c6cce803096b5cd4511cf0819ff517b
/// </summary>
public static class CooldownManager
{
private class HiddenMonobehaviour : MonoBehaviour { }
private static MonoBehaviour mono;
private static Dictionary<string,Coroutine> coroutines = new Dictionary<string, Coroutine>();
//TO SUPPORT DOMAIN RELOADING WHEN DISABLED
[RuntimeInitializeOnLoadMethod]
static void Init()
{
GameObject obj = new GameObject("Cooldown Manager");
obj.hideFlags = HideFlags.HideInHierarchy;
UnityEngine.Object.DontDestroyOnLoad(obj);
mono = obj.AddComponent<HiddenMonobehaviour>();
}
/// <summary>Delays <b>action</b> by <b>cooldownDurations (in seconds)</b></summary>
/// <param name="cooldownDuration">Duration in seconds</param>
public static Coroutine Cooldown(float cooldownDuration, Action action)
{
return mono.StartCoroutine(InternalCooldown(cooldownDuration, action));
}
/// <summary>Cooldown will delay the action by the cooldownDuration given (in seconds). If another coroutine with same name is running it will stop that one</summary>
/// <param name="cooldownDuration">Duration in seconds</param>
public static void Cooldown(float cooldownDuration, Action action, string name)
{
if (coroutines.ContainsKey(name))
mono.StopCoroutine(coroutines[name]);
coroutines[name] = mono.StartCoroutine(InternalCooldown(cooldownDuration, action));
}
public static Coroutine Cooldown<T>(float cooldownDuration, Action<T> action, T parameter)
{
return mono.StartCoroutine(InternalCooldown(cooldownDuration, action, parameter));
}
public static Coroutine Cooldown<T, U>(float cooldownDuration, Action<T, U> action, T param1, U param2)
{
return mono.StartCoroutine(InternalCooldown(cooldownDuration, action, param1, param2));
}
public static Coroutine Cooldown<T, U, X>(float cooldownDuration, Action<T, U, X> action, T param1, U param2, X param3)
{
return mono.StartCoroutine(InternalCooldown(cooldownDuration, action, param1, param2, param3));
}
private static IEnumerator InternalCooldown(float cooldownDuration, Action action)
{
yield return new WaitForSeconds(cooldownDuration);
action.Invoke();
}
private static IEnumerator InternalCooldown<T>(float cooldownDuration, Action<T> action, T parameter)
{
yield return new WaitForSeconds(cooldownDuration);
action.Invoke(parameter);
}
private static IEnumerator InternalCooldown<T, U>(float cooldownDuration, Action<T, U> action, T parameter1, U parameter2)
{
yield return new WaitForSeconds(cooldownDuration);
action.Invoke(parameter1, parameter2);
}
private static IEnumerator InternalCooldown<T, U, X>(float cooldownDuration, Action<T, U, X> action, T parameter1, U parameter2, X parameter3)
{
yield return new WaitForSeconds(cooldownDuration);
action.Invoke(parameter1, parameter2, parameter3);
}
public static Coroutine OnNextFrame(Action action)
{
return mono.StartCoroutine(InternalNextFrame(action));
}
private static IEnumerator InternalNextFrame(Action action)
{
yield return 0;
action.Invoke();
}
public static void IterateOverTime(float duration, Action action, int iterationsPerSecond = 60)
{
mono.StartCoroutine(InternalIterateOverTime(duration, action, iterationsPerSecond));
}
private static IEnumerator InternalIterateOverTime(float duration, Action action, int iterationsPerSecond)
{
WaitForSeconds wait = new WaitForSeconds(1f / iterationsPerSecond);
float startTime = Time.time;
for (float timePassed = 0; timePassed < duration; timePassed = Time.time - startTime)
{
action.Invoke();
yield return wait;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment