Godot Version
4.4.1
Question
I’m trying to make a cooldown bar using a TextureProgressBar with a custom shader that fills up like water. In my script I call cooldown.set_instance_shader_parameter(“progress”, value) every frame.
But something goes wrong, like this photo:
the shader, somehow start from the middle, or I can say it’s not depends on wait_timer, if the cooldown is 10, then it could be 1/4 way to end and the shader just start show up. In the default Timer Inspector, I set it to 3seconds.
shader:
shader_type canvas_item;
instance uniform float max_value = 2.0;
instance uniform float progress = 0.0; // nilai progress aktual
uniform float wave_speed = 1.0;
uniform float wave_amplitude = 0.04; // tinggi gelombang
uniform float wave_length = 2.5; // frekuensi gelombang
uniform float edge_softness = 0.02; // lembut
uniform vec4 fill_color : source_color = vec4(0.1, 0.5, 0.9, 1.0);
void fragment() {
// y_btm: 0 = bawah, 1 = atas
float y_btm = 1.0 - UV.y;
float base = clamp(progress / max_value, 0.0, 1.0);
float wave_fade = smoothstep(0.0, 0.02, base);
float wave = sin((UV.x * wave_length + TIME * wave_speed) * TAU) * wave_amplitude * wave_fade;
float level = clamp(base + wave, 0.0, 1.0);
float filled = 1.0 - smoothstep(level - edge_softness, level + edge_softness, y_btm);
COLOR = vec4(fill_color.rgb, filled * fill_color.a );
}
log :
Godot Engine v4.4.1.stable.official.49a5bc7b6 - https://godotengine.org
OpenGL API 3.3.0 NVIDIA 555.99 - Compatibility - Using Device: NVIDIA - NVIDIA GeForce MX110
button spawned
button spawned
button spawned
One casted from Player
ATTACK LAUNCHED !!!
[LOG:pressed]
timer.wait_time =6.0
timer.time_left =6.0
cooldown.max_val =6.0
shader.progress =3.0
shader.max_value =3.0
[LOG:process]
timer.wait_time =6.0
timer.time_left =6.0
cooldown.max_val =6.0
shader.progress =0.0
shader.max_value =6.0
[LOG:process]
timer.wait_time =6.0
timer.time_left =5.98333333333333
cooldown.max_val =6.0
shader.progress =0.01666666666667
shader.max_value =6.0
[LOG:process]
timer.wait_time =6.0
timer.time_left =5.96666666666667
cooldown.max_val =6.0
shader.progress =0.03333333333333
shader.max_value =6.0
[LOG:process]
timer.wait_time =6.0
timer.time_left =5.95
cooldown.max_val =6.0
shader.progress =0.05
shader.max_value =6.0
[LOG:process]
timer.wait_time =6.0
timer.time_left =5.93575333333333
cooldown.max_val =6.0
shader.progress =0.06424666666667
shader.max_value =6.0
[LOG:process]
timer.wait_time =6.0
timer.time_left =5.92047555555556
cooldown.max_val =6.0
shader.progress =0.07952444444444
shader.max_value =6.0
[LOG:process]
timer.wait_time =6.0
timer.time_left =5.900321
cooldown.max_val =6.0
shader.progress =0.099679
shader.max_value =6.0
[LOG:process]
timer.wait_time =6.0
timer.time_left =5.88365433333333
cooldown.max_val =6.0
shader.progress =0.11634566666667
shader.max_value =6.0
[LOG:process]
timer.wait_time =6.0
timer.time_left =5.86693
cooldown.max_val =6.0
shader.progress =0.13307
shader.max_value =6.0
[LOG:process]
timer.wait_time =6.0
timer.time_left =5.85026333333333
cooldown.max_val =6.0
shader.progress =0.14973666666667
shader.max_value =6.0
[LOG:process]
timer.wait_time =6.0
timer.time_left =5.83359666666667
cooldown.max_val =6.0
shader.progress =0.16640333333333
shader.max_value =6.0
[LOG:process]
timer.wait_time =6.0
timer.time_left =5.81693
cooldown.max_val =6.0
shader.progress =0.18307
shader.max_value =6.0
[LOG:process]
timer.wait_time =6.0
timer.time_left =5.80026333333333
cooldown.max_val =6.0
shader.progress =0.19973666666667
shader.max_value =6.0
[LOG:process]
timer.wait_time =6.0
timer.time_left =5.78359666666667
cooldown.max_val =6.0
shader.progress =0.21640333333333
shader.max_value =6.0
[LOG:process]
timer.wait_time =6.0
timer.time_left =5.76693
cooldown.max_val =6.0
shader.progress =0.23307
shader.max_value =6.0
[LOG:process]
timer.wait_time =6.0
timer.time_left =5.75026333333333
cooldown.max_val =6.0
shader.progress =0.24973666666667
shader.max_value =6.0
[LOG:process]
timer.wait_time =6.0
timer.time_left =5.73220777777778
cooldown.max_val =6.0
shader.progress =0.26779222222222
shader.max_value =6.0
[LOG:process]
timer.wait_time =6.0
timer.time_left =5.71415222222222
cooldown.max_val =6.0
shader.progress =0.28584777777778
shader.max_value =6.0
[LOG:process]
timer.wait_time =6.0
timer.time_left =5.69609666666667
cooldown.max_val =6.0
shader.progress =0.30390333333333
shader.max_value =6.0
[LOG:process]
timer.wait_time =6.0
timer.time_left =5.67804111111111
cooldown.max_val =6.0
shader.progress =0.32195888888889
shader.max_value =6.0
......
......
[LOG:process]
timer.wait_time =6.0
timer.time_left =2.99105266666667
cooldown.max_val =6.0
shader.progress =3.00894733333333
shader.max_value =6.0
[LOG:process]
timer.wait_time =6.0
timer.time_left =2.97438600000001
cooldown.max_val =6.0
shader.progress =3.02561399999999
shader.max_value =6.0
[LOG:process]
timer.wait_time =6.0
timer.time_left =2.95771933333334
cooldown.max_val =6.0
shader.progress =3.04228066666666
shader.max_value =6.0
[LOG:process]
timer.wait_time =6.0
timer.time_left =2.94105266666667
cooldown.max_val =6.0
shader.progress =3.05894733333333
shader.max_value =6.0
[LOG:process]
timer.wait_time =6.0
timer.time_left =2.92438600000001
cooldown.max_val =6.0
shader.progress =3.07561399999999
shader.max_value =6.0
[LOG:process]
timer.wait_time =6.0
timer.time_left =2.90771933333334
cooldown.max_val =6.0
shader.progress =3.09228066666666
shader.max_value =6.0
[LOG:process]
timer.wait_time =6.0
timer.time_left =2.89105266666667
cooldown.max_val =6.0
shader.progress =3.10894733333333
shader.max_value =6.0
[LOG:process]
timer.wait_time =6.0
timer.time_left =2.87438600000001
cooldown.max_val =6.0
shader.progress =3.12561399999999
shader.max_value =6.0
[LOG:process]
timer.wait_time =6.0
timer.time_left =2.85771933333334
cooldown.max_val =6.0
shader.progress =3.14228066666666
shader.max_value =6.0
[LOG:process]
timer.wait_time =6.0
timer.time_left =2.84105266666668
cooldown.max_val =6.0
shader.progress =3.15894733333332
shader.max_value =6.0
[LOG:process]
timer.wait_time =6.0
timer.time_left =2.82438600000001
cooldown.max_val =6.0
shader.progress =3.17561399999999
shader.max_value =6.0
[LOG:process]
timer.wait_time =6.0
timer.time_left =2.80771933333334
cooldown.max_val =6.0
shader.progress =3.19228066666666
shader.max_value =6.0
[LOG:process]
timer.wait_time =6.0
timer.time_left =2.79105266666668
cooldown.max_val =6.0
shader.progress =3.20894733333332
shader.max_value =6.0
[LOG:process]
timer.wait_time =6.0
timer.time_left =2.77438600000001
cooldown.max_val =6.0
shader.progress =3.22561399999999
shader.max_value =6.0
[LOG:process]
timer.wait_time =6.0
timer.time_left =2.75771933333334
cooldown.max_val =6.0
shader.progress =3.24228066666666
shader.max_value =6.0
[LOG:process]
timer.wait_time =6.0
timer.time_left =2.74105266666668
cooldown.max_val =6.0
shader.progress =3.25894733333332
shader.max_value =6.0
[LOG:process]
timer.wait_time =6.0
timer.time_left =2.72438600000001
cooldown.max_val =6.0
shader.progress =3.27561399999999
shader.max_value =6.0
[LOG:process]
timer.wait_time =6.0
timer.time_left =2.70771933333334
cooldown.max_val =6.0
shader.progress =3.29228066666666
shader.max_value =6.0
[LOG:process]
timer.wait_time =6.0
timer.time_left =2.69105266666668
cooldown.max_val =6.0
shader.progress =3.30894733333332
shader.max_value =6.0
[LOG:process]
timer.wait_time =6.0
timer.time_left =2.67438600000001
cooldown.max_val =6.0
shader.progress =3.32561399999999
shader.max_value =6.0
[LOG:process]
timer.wait_time =6.0
timer.time_left =2.65771933333334
cooldown.max_val =6.0
shader.progress =3.34228066666666
shader.max_value =6.0
[LOG:process]
timer.wait_time =6.0
timer.time_left =2.64105266666668
cooldown.max_val =6.0
shader.progress =3.35894733333332
shader.max_value =6.0
[LOG:process]
timer.wait_time =6.0
timer.time_left =2.62438600000001
cooldown.max_val =6.0
shader.progress =3.37561399999999
shader.max_value =6.0
[LOG:process]
timer.wait_time =6.0
timer.time_left =2.60771933333334
cooldown.max_val =6.0
shader.progress =3.39228066666666
shader.max_value =6.0
[LOG:process]
timer.wait_time =6.0
timer.time_left =2.59105266666668
cooldown.max_val =6.0
shader.progress =3.40894733333332
shader.max_value =6.0
[LOG:process]
timer.wait_time =6.0
timer.time_left =2.57438600000001
cooldown.max_val =6.0
shader.progress =3.42561399999999
shader.max_value =6.0
[LOG:process]
timer.wait_time =6.0
timer.time_left =2.55771933333334
cooldown.max_val =6.0
shader.progress =3.44228066666666
shader.max_value =6.0
[LOG:process]
timer.wait_time =6.0
timer.time_left =2.54105266666668
cooldown.max_val =6.0
shader.progress =3.45894733333332
shader.max_value =6.0
[LOG:process]
timer.wait_time =6.0
timer.time_left =2.52438600000001
cooldown.max_val =6.0
shader.progress =3.47561399999999
shader.max_value =6.0
[LOG:process]
timer.wait_time =6.0
timer.time_left =2.50771933333334
cooldown.max_val =6.0
shader.progress =3.49228066666666
shader.max_value =6.0
[LOG:process]
timer.wait_time =6.0
timer.time_left =2.49105266666668
cooldown.max_val =6.0
shader.progress =3.50894733333332
shader.max_value =6.0
[LOG:process]
timer.wait_time =6.0
timer.time_left =2.47438600000001
cooldown.max_val =6.0
shader.progress =3.52561399999999
shader.max_value =6.0
[LOG:process]
timer.wait_time =6.0
timer.time_left =2.45771933333334
cooldown.max_val =6.0
shader.progress =3.54228066666666
shader.max_value =6.0
[LOG:process]
timer.wait_time =6.0
timer.time_left =2.44105266666668
cooldown.max_val =6.0
shader.progress =3.55894733333332
shader.max_value =6.0
[LOG:process]
timer.wait_time =6.0
timer.time_left =2.42438600000001
cooldown.max_val =6.0
shader.progress =3.57561399999999
shader.max_value =6.0
[LOG:process]
timer.wait_time =6.0
timer.time_left =2.40771933333334
cooldown.max_val =6.0
shader.progress =3.59228066666666
shader.max_value =6.0
[LOG:process]
timer.wait_time =6.0
timer.time_left =2.39105266666668
cooldown.max_val =6.0
shader.progress =3.60894733333332
shader.max_value =6.0
....
.....
[LOG:process]
timer.wait_time =6.0
timer.time_left =0.17438600000001
cooldown.max_val =6.0
shader.progress =5.82561399999999
shader.max_value =6.0
[LOG:process]
timer.wait_time =6.0
timer.time_left =0.15771933333335
cooldown.max_val =6.0
shader.progress =5.84228066666665
shader.max_value =6.0
[LOG:process]
timer.wait_time =6.0
timer.time_left =0.14105266666668
cooldown.max_val =6.0
shader.progress =5.85894733333332
shader.max_value =6.0
[LOG:process]
timer.wait_time =6.0
timer.time_left =0.12438600000001
cooldown.max_val =6.0
shader.progress =5.87561399999999
shader.max_value =6.0
[LOG:process]
timer.wait_time =6.0
timer.time_left =0.10771933333335
cooldown.max_val =6.0
shader.progress =5.89228066666665
shader.max_value =6.0
[LOG:process]
timer.wait_time =6.0
timer.time_left =0.09105266666668
cooldown.max_val =6.0
shader.progress =5.90894733333332
shader.max_value =6.0
[LOG:process]
timer.wait_time =6.0
timer.time_left =0.07438600000001
cooldown.max_val =6.0
shader.progress =5.92561399999999
shader.max_value =6.0
[LOG:process]
timer.wait_time =6.0
timer.time_left =0.05771933333335
cooldown.max_val =6.0
shader.progress =5.94228066666665
shader.max_value =6.0
[LOG:process]
timer.wait_time =6.0
timer.time_left =0.04105266666668
cooldown.max_val =6.0
shader.progress =5.95894733333332
shader.max_value =6.0
[LOG:process]
timer.wait_time =6.0
timer.time_left =0.02438600000001
cooldown.max_val =6.0
shader.progress =5.97561399999999
shader.max_value =6.0
[LOG:process]
timer.wait_time =6.0
timer.time_left =0.00771933333335
cooldown.max_val =6.0
shader.progress =5.99228066666665
shader.max_value =6.0
[LOG:timeout]
timer.wait_time =6.0
timer.time_left =5.99105266666668
cooldown.max_val =6.0
shader.progress =5.99228066666665
shader.max_value =6.0
--- Debugging process stopped ---
skill_button.gd:
extends TextureButton
@onready var cooldown: TextureProgressBar = $Cooldown
@onready var key: Label = $key
@onready var time_counter: Label = $time_counter
@onready var timer: Timer = $Timer
var skill = null
var change_key := "":
set(value):
change_key = value
key.text = value
shortcut = Shortcut.new()
var input_key = InputEventKey.new()
input_key.keycode = value.unicode_at(0)
shortcut.events = [input_key]
func _ready():
print("button spawned")
change_key = "1"
# max_value bar = lama timer
cooldown.max_value = timer.wait_time
cooldown.modulate.a = 0.0
# kasih parameter awal ke shader
cooldown.set_instance_shader_parameter("max_value", timer.wait_time)
cooldown.set_instance_shader_parameter("progress", timer.wait_time - timer.time_left)
set_process(false)
func _process(_delta):
time_counter.text = "%3.1f" % timer.time_left
if timer.is_stopped():
cooldown.set_instance_shader_parameter("progress", 0.0)
else:
var p = timer.wait_time - timer.time_left # nilai 0..wait_time
cooldown.set_instance_shader_parameter("progress", p)
cooldown.set_instance_shader_parameter("max_value", timer.wait_time)
# panggil logger tiap frame
_log_status("process")
func _on_pressed():
if skill != null :
skill.exec_skill(owner.find_child("Player"))
cooldown.modulate.a = 1.0
timer.start()
disabled = true
set_process(true)
_log_status("pressed")
func _on_timer_timeout():
disabled = false
time_counter.text = ""
set_process(false)
cooldown.modulate.a = 0.0
_log_status("timeout")
# ------------------------------
# Fungsi khusus logging lengkap
# ------------------------------
func _log_status(source: String) -> void:
var shader_p = cooldown.get_instance_shader_parameter("progress")
var shader_m = cooldown.get_instance_shader_parameter("max_value")
print("\n[LOG:", source, "]",
"\n timer.wait_time =", timer.wait_time,
"\n timer.time_left =", timer.time_left,
"\n cooldown.max_val =", cooldown.max_value,
"\n shader.progress =", shader_p,
"\n shader.max_value =", shader_m,
)
skill.gd:
extends Resource
class_name Skill
var cooldown: float
var texture: Texture2D
var animation_name: String
func _init(target):
target.cooldown.max_value = cooldown
target.texture_normal = texture
target.timer.wait_time = cooldown
func exec_skill(target):
print(animation_name + " casted from " + target.name)
skill1.gd:
extends Skill
class_name FirstSkill
func _init(target):
cooldown = 6.0
animation_name = "One"
texture = preload("res://Assets/Sprites/Icons/skill_icon_12.png")
super._init(target)
func exec_skill(target):
super.exec_skill(target)
target.launch_attack()
skill_slots.gd:
extends HBoxContainer
var skill_slots: Array
func _ready() -> void:
skill_slots = get_children()
for i in get_child_count():
skill_slots[i].change_key = str(i+1)
skill_slots[0].skill = FirstSkill.new(skill_slots[0])
skill_slots[1].skill = SecondSkill.new(skill_slots[1])
skill_slots[2].skill = ThirdSkill.new(skill_slots[2])