Make function work for n seconds (c#)


I’m trying to create a Regeneration method on my PlayerHealth class (Unity survival shooter tutorial is the base of my project).

I want to be able to call regeneration from anywhere and make it go for N seconds. It seems like a good idea to make it Update() independent

My version is:

public int CurrentHealth;

public void Regenerate (float HpPerSecond, short Duration)
    CurrentHealth += int(HpPerSecond*Time.deltaTime);
    if(Duration > 0)
        Regenerate(HpPerSecond, Duration);


However for some reason in-game my HP doesn’t change when I call the function as PlayerHealth.Regenerate (5,5);

Also, if I add Debug.Log into the code for some testing, it almost freezes. so the question is, what is the right approach to the problem? (I want a good way, not the fastest to code)

You’re probably losing all fractional calcs due to your CurrentHealth var being an int. Try making it a float.

If you want to make something that’s not on the Update function but takes more than one frame to finish use a coroutine. Something similar to this should work:

public IEnumerator Regenerate(float hppersecond, float duration)
    while (duration > 0) {
        if(currentHealth <= maximumHealth)
            currentHealth += hppersecond * Time.deltaTime;
        Debug.Log ("cur=" + currentHealth + " hppersec=" + hppersecond + " dur=" + duration);

        updateHealthBar ();

        duration -= Time.deltaTime;
        yield return null;

When you want to start regeration call this method from a script:


Coroutines run until a “yield return null” line, stop there, return control to unity, and continue from that point in the next frame. You can return other things instead of null to control when to continue the coroutine.

What you wrote as a comment in MGB answer regenerates all the HP in one frame because you made a recursive function that won’t return control to unity’s engine until it finishes (and it only finishes after Duration is 0 or less). Everything will hapen in one frame.

Also, it kind of freezes when you add a Debug.Log() line in there for 2 things:

  • Printing to the console takes a considerable time compared to other operations
  • Time.deltaTime usually have a really small value (like 0.02 or even less), so it takes like 250 or more recursive calls to finish the Regenerate execution.