- Home /
Executing a list of coroutines at specific times
I would like to be able to execute a list of coroutines at specific times and allow this list to be serialized.
To implement this I thought that I would create a base "Script" class:
public abstract class Script
{
IEnumerator action;
float time;
public Script(ScriptSettings settings)
{
time = settings.Time;
}
public void Execute()
{
float elapsedTime = time - Time.time;
// Check to see if the script has expired
if (elapsedTime < 0)
{
return;
}
OnExecute(elapsedTime);
}
protected abstract void OnExecute(float elapsedTime);
}
The derived classes would then have the specific coroutine or "action" which would be called from Execute:
public class Fire : Script
{
IEnumerator action;
float time;
public Fire(ScriptSettings settings)
: base(settings)
{
}
protected override void OnExecute(float elapsedTime)
{
StartCoroutine(Firing(elapsedTime)); // Can't use this function outside of a MonoBehaviour derived class
}
IEnumerator Firing(float startTime)
{
yield return new WaitForSeconds(startTime);
// Fire
Debug.Log("Fire " + Time.time);
}
}
This method fails to work as I can't derive from both MonoBehaviour and Script.
What methods do you guys use for executing a list of coroutines at specific times?
It would normally seem straightforward but I will need to serialize each type of coroutine and the time at which it will execute. The time part is easy but I thought the coroutine will require a specific class to which it is associated?
Answer by dscroggi · Jan 21, 2014 at 11:57 PM
Hmm how about a timer script with a public static method that can register your coroutines and call from your OnExecute?
using System;
using System.Collections.Generic;
using UnityEngine;
public class Timer : MonoBehaviour
{
private static Dictionary<Action, float> timers = new Dictionary<Action, float>();
public static void Set(Delegate callback, float duration, float delay = 0, params object[] parameters)
{
if(delay > 0)
{
timers.Add(() => timers.Add(() => callback.DynamicInvoke(parameters), duration), delay);
}
else
{
timers.Add(() => callback.DynamicInvoke(parameters), duration);
}
}
private void Update()
{
foreach (KeyValuePair<Action, float> timer in timers)
{
if(timer.Value >= 0)
{
timers.Remove(timer.Key);
timer.Key();
}
else
{
timers[timer.Key] -= Time.deltaTime;
}
}
}
}
Looking good. I was hoping to avoid accumulating time each update by setting WaitForSeconds in a Coroutine but this is certainly useful. Thank you.
Your answer

Follow this Question
Related Questions
A node in a childnode? 1 Answer
Difference between assigning a value in inspector and with a custom editor script 1 Answer
Problems in a footstep coroutine 1 Answer
What is the best method to have a list of references to other scripts? 0 Answers
How do I make child classes in a list editable from the Inspector? 1 Answer