Tweens on a textureprogress bar

Godot Version

v4.2.1

Question

Hello, i want to make resource bars with smooth transitions between values, so no jumping from half to full life in an instant for example. So i used a tween for the value of the progress bar which works great:

func _process(delta):
    if Input.is_action_just_pressed("ui_accept"):
        var stamina_tween = stamina.value - 10
        var tween = create_tween()
        tween.tween_property(stamina, "value", stamina_tween, 0.2 )
        print(stamina.value)

the “problem” is if any change to the value is happening while the tween is running the result will be something like this:

i can block changes to the value with a timer that has the same duration as the tween but that does not work on a bar that is regenerating or is poisoned.

As i said the goal are smooth transitions on the progress bar, how do i “pool” changes to the progress bar value? Is my attempt with tween even a good idea?

I think you can have a varibale to add up values while your tween animation is running.

So, if the tween is running while trying to change the value, you add it up to a temp variable.

exends {YourParentNode}
class_name HealthBar

var cached_value : int = 0
var tween: Tween

func change_health (amount : int) -> void:
   if tween != null && tween.is_running():
      cached_value += amount
   else:
      create_tween(amount)

func create_tween(amount : int) -> void:
    pass # Your code here to create the tween and play it.

# Suscribe to your tween "finished" signal
func _on_tween_finished():
   if cached_value != 0:
      create_tween(cached_value)
      cached_value = 0

(Also, I think that you can replace cached_value with an Array, and use it like a queue, then add to the last position when the tween is runing, and remove the first to consume it on tween finished).

In general, your “cahed_value” should be the “stamina”, try to have a model with the player stamina, then apply all the changes to that model.
Then you can do a signal in that model like “stamina_changed”, and suscribe from your UI, and there create the tween, then when the tween finishes read the value from the model, to see if you need to update the value in the progress bar.

I tried to implement this but i am getting the same error until i just tried to do everything exactly as you showed with the same result:

is the problem that the function create_tween() has the same name as the method?

Yes, that’ll be it. Godot thinks you’re trying to override the Node.create_tween() function, which doesn’t have any arguments. Just name it differently, and it should be fine.

Ah okay, i actually did rename it for testing which removed all the errors but the code did not do anything.
I will have to check everything when i am back home as i am missing something else it seems.