- Home /
How to Make Health Decrease Over Time
Hi all,
I have been trying without luck to implement other people's code from similar questions to my own script. Basically I have a health bar that I would like to be constantly ticking down e.g. losing 1 health point/second. Here is the code, any help would be greatly appreciated. Thanks in advance.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class HealthController : MonoBehaviour
{
public UnityEngine.Events.UnityEvent OnDeath;
[SerializeField] public float playerHealth;
[SerializeField] public float maxHealth;
[SerializeField] public Image healthImage;
[SerializeField] public int damage;
void Start()
{
}
public void ButtonClick()
{
playerHealth -= damage;
UpdateHealth();
if(playerHealth < 0)
OnDeath.Invoke();
}
private void UpdateHealth()
{
healthImage.fillAmount = playerHealth / maxHealth;
}
}
Answer by RodrigoAbreu · Feb 09, 2021 at 04:55 AM
@emersonmaxwell, you can do that in different ways, here are 3:
InvokeRepeating
void Start () { InvokeRepeating("UpdateHealth", 1f, 1f); //1s delay, repeat every 1s } void UpdateHealth() { }
Coroutine
IEnumerator Start() { while(true) { yield return new WaitForSeconds(1f); UpdateHealth(); } } void UpdateHealth() { }
Update
float elapsed = 0f; void Update() { elapsed += Time.deltaTime; if (elapsed >= 1f) { elapsed = elapsed % 1f; UpdateHealth(); } } void UpdateHealth() { }
Answer by emersonmaxwell · Feb 09, 2021 at 03:00 PM
Thank you very much Rodrigo this works perfectly and I really appreciate your help. I used your second method like so:
[SerializeField] public int damagetaken;
IEnumerator Start()
{
while (true)
{
yield return new WaitForSeconds(2f);
playerHealth += damagetaken;
UpdateHealth();
}
}
Then in the Inspector I am able to add a value to the Damage Taken thus controlling how much damage per second occurs.
Thanks again!
Cool, yeah you can also do something like this:
IEnumerator Start()
{
while (playerHealth > 0)
{
yield return new WaitForSeconds(2f);
playerHealth -= damagetaken;
UpdateHealth();
}
if (playerHealth < 0)
{
playerHealth = 0;
}
OnDeath.Invoke();
}
Passing the damagetaken as a negative value in the inspector might be a bit confusing, so I'd pass it as a plain positive number and subtract on damage instead. Another thing you could also pass via inspector is the damageFrequency instead of hardcoding 2f : yield return new WaitForSeconds(2f). Just some ideas.