I have a coroutine that is supposed to be in synced with my Update (or FixedUpdate) method. However when I disable my script (pausing Update and FixedUpdate), the coroutine continues to run… Basically, what I want to happen is for the WaitForSeconds() timer to use also Time.deltaTime/Time.fixedDeltaTime, but it doesn’t. What could be my alternative? Is there a way to write a WaitForSeconds() method but sync its timer with Update so when I disable my script the timer also pauses and resumes when I re-enable my script?
Here is a code reference:
void Start()
{
StartCoroutine("HealTimer");
}
IEnumerator HealTimer()
{
while (true)
{
yield return new WaitForSeconds(1f);
hp += 20;
}
}
PS. Please don’t suggest to put the code in Update/FixedUpdate instead. I really want to use coroutines here. Thank you.
Edit: To layout the context of this question…
I have a Pausable component, which basically disables the other scripts attached to the gameObject. So what I want to happen is that, when I pause my gameObject (disable the script), I could pause the WaitForSecs() coroutine.
I have solved the problem… What I did was I created a timer for my Pausable component. Below is the layout of my game object and the trimmed down code:
[21729-screenshot+2014-02-05+06.36.38.png|21729]
Pausable Component:
public class Pausable : MonoBehaviour
{
// holds all scripts currently paused
private List<MonoBehaviour> m_pausedScripts = new List<MonoBehaviour>();
// this is used to support pausing of WaitForSeconds() when using coroutine
float m_timer = 0;
// is this gameObject currently paused?
private bool m_isPaused = false;
void Update()
{
if (!m_isPaused)
{
m_timer += Time.deltaTime;
}
}
public void Pause()
{
// label as paused
m_isPaused = true;
// pause scripts
MonoBehaviour[] scripts = this.GetComponents<MonoBehaviour>();
foreach (MonoBehaviour script in scripts)
{
// skip this script
if (script is Pausable)
continue;
// pause only enabled scripts
if (!script.enabled)
continue;
// pause the script
script.enabled = false;
}
}
public void Resume()
{
// label as unpaused
m_isPaused = false;
// resume paused scripts
foreach (MonoBehaviour script in m_pausedScripts)
{
// pause the script
script.enabled = true;
}
}
public IEnumerator WaitForSeconds(float secs)
{
float startTime = this.m_timer;
while (true)
{
if (this.m_timer - startTime >= secs)
{
yield break;
}
yield return null;
}
}
}
Test script
public class Test : MonoBehaviour
{
void Start()
{
// start heal timer
StartCoroutine("HealTimer");
}
IEnumerator HealDamageTimer()
{
while (true)
{
Pausable pausable = GetComponent<Pausable>();
yield return StartCoroutine(pausable.WaitForSeconds(1f));
hp += 20;
}
}
}
Now, the WaitForSeconds() pauses when I pause my gameObject. And resumes when I resume it. Hope it helps!