Skip to content

Instantly share code, notes, and snippets.

@123tris
Last active September 9, 2024 08:01
Show Gist options
  • 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;
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");
UnityEngine.Object.DontDestroyOnLoad(obj);
mono = obj.AddComponent<HiddenMonobehaviour>();
coroutines = new Dictionary<string, Coroutine>();
}
/// <summary>Delays <b>action</b> by <b>cooldownDurations (in seconds)</b></summary>
/// <param name="cooldownDuration">Duration in seconds</param>
public static CoroutineHandler 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 CoroutineHandler Cooldown<T>(float cooldownDuration, Action<T> action, T parameter)
{
return mono.StartCoroutine(InternalCooldown(cooldownDuration, action, parameter));
}
public static CoroutineHandler Cooldown<T, TU>(float cooldownDuration, Action<T, TU> action, T param1, TU param2)
{
return mono.StartCoroutine(InternalCooldown(cooldownDuration, action, param1, param2));
}
public static CoroutineHandler Cooldown<T, TU, TX>(float cooldownDuration, Action<T, TU, TX> action, T param1, TU param2, TX 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, TU>(float cooldownDuration, Action<T, TU> action, T parameter1, TU parameter2)
{
yield return new WaitForSeconds(cooldownDuration);
action.Invoke(parameter1, parameter2);
}
private static IEnumerator InternalCooldown<T, TU, TX>(float cooldownDuration, Action<T, TU, TX> action, T parameter1, TU parameter2, TX parameter3)
{
yield return new WaitForSeconds(cooldownDuration);
action.Invoke(parameter1, parameter2, parameter3);
}
public static CoroutineHandler OnNextFrame(Action action)
{
return mono.StartCoroutine(InternalNextFrame(action));
}
private static IEnumerator InternalNextFrame(Action action)
{
yield return 0;
action.Invoke();
}
public static CoroutineHandler Repeat(Action action, float repeatInterval, float duration = -1)
{
return mono.StartCoroutine(InternalIterateOverTime(action, repeatInterval, duration));
}
private static IEnumerator InternalIterateOverTime(Action action, float repeatInterval, float duration = -1)
{
WaitForSeconds wait = new WaitForSeconds(repeatInterval);
float startTime = Time.time;
while (duration == -1)
{
action.Invoke();
yield return wait;
}
for (float timePassed = 0; timePassed < duration; timePassed = Time.time - startTime)
{
action.Invoke();
yield return wait;
}
}
public static CoroutineHandler Cooldown(this MonoBehaviour behaviour, float cooldownDuration, Action action)
{
return behaviour.StartCoroutine(InternalCooldown(cooldownDuration, action));
}
public class CoroutineHandler
{
public Coroutine Coroutine { get; }
private CoroutineHandler(Coroutine coroutine)
{
Coroutine = coroutine;
}
public void StopCoroutine()
{
mono.StopCoroutine(Coroutine);
}
public static implicit operator CoroutineHandler(Coroutine coroutine) => new CoroutineHandler(coroutine);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment