I have tower and it uses a coroutine to attack and I have created a pause state for my game. When I pause the game I stop my coroutines and it stops too but the problem begins here. My turret has a cooldown which is 3 seconds and I pause the game exactly when my tower make its attack. Now what I expect from my tower is to attack when I resume the game after 3 seconds. However lets say I wait 2 seconds in pause state and then I resume. In this case, my tower attack after 1 second which means the time keep passing behind my coroutine. How can I solve this problem?
How are you pausing the game? How are you counting time in the coroutines?
You could just make your own timer to handle stuff like this.
It’s generally worth it because sometimes things like these need multiple timers as well as ways to reset it or to know how much time is remaining.
Wrote this simple example for similar question on tigsource
//Timer.cs
public class Timer
{
public float Duration { get; private set; }
public float Remaining { get; private set; }
public bool Running { get; private set; }
public void Start(float time)
{
Duration = time;
Remaining = time;
Running = true;
}
public void Reset()
{
Remaining = 0.0f;
Duration = 0.0f;
Running = false;
}
public void Restart()
{
Remaining = Duration;
}
public bool Tick(float dt)
{
if (!Running)
return false;
if (0.0f > Remaining)
{
return true;
}
else
{
Remaining -= dt;
return false;
}
}
}
//Test.cs
public class Test : MonoBehaviour
{
Timer exampleTimer = new Timer();
void Start ()
{
exampleTimer.Start(1.0f);
}
void Update ()
{
if(exampleTimer.Tick(Time.deltaTime))
{
exampleTimer.Restart();
Debug.Log("Tick");
}
}
}
I do not have my timer and I have a pause state. When state is pause then I stop everything in Update. Even my coroutines working in Update. The problem is I pause the game after my tower makes its attack and it has 3 seconds cooldown. When I pause the game and then resume the game tower should attack exactly after 3 seconds. However if I wait 3 seconds in Pause state, it attacks instantly because the time keep passing behind coroutine.
Stopping Co-routine resets it’s timer, hence is why I’d recommend using separate timers instead because that way you can just not tick/update them when the game is paused.
With co-routines issues like these tend to get very messy because you’d need to keep track how long the co-routine has been running and using it instead of normal delay when re-starting co-routines after pause.
I solved my problem with WaitUntil. I was using “yield return new WaitForSeconds(1/FireSpeed);”
In here FireSpeed my tower’s cooldown. Now I am using “yield return new WaitUntil(() => !ManagerInstance.IsPaused”
and I added this to update:
if(!ManagerInstance.IsPaused)
releaseTime -= Time.deltaTime;
Now It works perfect. Thank you for your answer mate.