Smooth fillAmount UI Image

I’m trying to make the health system for the character.
I have this Damage function:

public void Damage(float damagaValue){
     Image.GetCompinent<Image>().fillAmount -= damageValue / 100; //I divide by 100 because the damageValue is between 0 and 100 and the filAmount is by 0 and 1
     
}

Mostly I call the Damage() function in OnTriggerEnter() or OnCollisionEnter()
I’m trying to make an smooth trainsition of damage.
I tried:

smoothValue = Mathf.Lerp(Image.GetCompinent<Image>().fillAmount, damageValue / 100, Time.deltaTime * speed);
Image.GetCompinent<Image>().fillAmount -= smoothValue;

I is not working and I think it requires a repetitive function or a while and I call it in OnTriggerEnter.

If you want the health bar to adjust smoothly, then you should have a separate variable somewhere that represents how much health you “really” have (this variable should update instantly) and then use an Update() function to make the health bar gradually change to reflect the current value of that variable.

1 Like

Thank you! Can you give me an example?

@MikeyJY

Why not try it yourself, you already have pretty much all the info needed;

Store the actual value, and the visual value that the bar has currently.

As the effect is not happening at once (= in one frame), you cannot just set the value like you have in your example.

You need to either do it in (for example) Update like @Antistone said, using some condition to decide if you need to animate.

Or use Coroutine. Then it is a matter of blending from current “visual” value to “real” value, like @Antistone said. Lerp from your current visual value to actual value. That way you can go either direction, plus or minus.

I implemented it and it is working, thanks!

@MikeyJY Can you please send me the code what you actually did?

I don’t have the code anymore, I remember that I had a variable called actualHealth and healh. In OnTriggerEnter I modified the actualHealth and update the health in Update to match the actual health:

void OnTriggerEnter(Collider other){
      PlayerStats.Damage(20);
}
void Damage(float hp){
      health=actualHealth; //before damaging make them equal because health can be slightly less then actualHealth because we subtract deltaTime repetitively from health while actualHealth is less then health and after that health can be with some decimals less then actualHealth;
     actualHealth -= hp;

}

void Update(){
if(actualHealth < health){
    health -= Time.deltaTime * speed;
    Image.GetCompinent<Image>().fillAmount -= health/100;
  
}

}

Actually your code works, it just has some little mistakes :smile:

float smoothHealth = Mathf.Lerp(healthBar.fillAmount, health / 100f, 0.5f);
healthBar.fillAmount = smoothHealth;