Gradually decrease node opacity with gdscript

Godot Version

4.3

Question

I am trying to find a way to get a label node to fade in. It has an initial opacity of 100% but I can’t find a way to bring it down using gdscript. I don’t want to use the animation player.

I’m trying to access and alter the alpha value with a script attached to the root node of the scene but find no real way of progressing.
I guess it should be convenient to add some function like if key is pressed, fade out this node, free queue of this node, fade in next node, to get a series of text labels?

Anyone want to share some thoughts?

Script:

extends Control

@onready var rich_text_label = $CanvasLayer/RichTextLabel

func _ready():
rich_text_label.self_modulate.a

Do like this:

var fade_duration = 1.0

func _ready():
   fade_in()

func fade_in():
   var tween = get_tree().create_tween()
   tween.tween_property(rich_text_label, "modulate:a", 0, fade_duration)
   tween.play()
   await tween.finished
   tween.kill()

func fade_out():
   var tween = get_tree().create_tween()
   tween.tween_property(rich_text_label, "modulate:a", 1, fade_duration)
   tween.play()
   await tween.finished
   tween.kill()

Paste the codes to the script and press CTRL + S

2 Likes

Thanks a lot! I appreciate you taking the time to help out!

I tried adding the script to the control node (root). I’ve also tried it on the richtextlabel node. In both cases nothing seems to happen. Hmm. I checked if the label is visible by manually increasing the a value and it becomes visible then.
I’m just wondering if there could be any problem, like with which node the script is attached to within the scene? I have changed the node the script extends when I’ve tried it on different nodes by the way.

Never heard about “tween” before, so I will make sure to read up on that as well. Thank you again!

1 Like

You just need to attach it with the world or main node

Please can you show a screenshot of the label properties

OK!
It is attached to the main node of the scene, a control node.
The settings of the richtextlabel node are 100% default settings except text has been added.
I noticed now that if I set opacity to more than 0, it goes down to 0 on load. So it seems to do the right thing but opposite? Going down instead of up

You need to change the modulate to default white, 1 alpha so it will work in game when you fade in

Ok just make the changes:

func _ready():
   rich_text_label.modulate.a = 1
   await get_tree().create_timer(1).timeout
   fade_in()

Now it starts fully faded in and then starts fading out after about a second or so.
Color is default white. Modulate starts out set to 1.

1 Like

Sounds like its working well, nice.

1 Like

Yes! The only remaining problem is that I want the text to start as fully opaque, fade in when the scene loads and then fade out at the press of any button.
I have been trying to change some values here and there but can’t get it to start fully opaque.
Is it possible to add some if statement to solve the last part?
Maybe something like If Input.is_action_just_pressed(“what do i write here for any button?”) at the start of the fade_out function?

do like this:

func _physical_process(_delta):
    If Input.is_action_just_pressed(“ui_accept”):
        fade_out()

Please can you show the codes or a screenshot of it.

Here is the code.

I changed one thing from how you wrote it.
Under _ready, i set rich_text_label.modulate.a to 0 instead of to 1, because when it was set to 1, the text started already faded in.

extends Control

@onready var rich_text_label = $CanvasLayer/RichTextLabel

var fade_duration = 1.0

func _ready():
rich_text_label.modulate.a = 0
await get_tree().create_timer(1).timeout
fade_in()

func _physical_process(_delta):
if Input.is_action_pressed(“ui_accept”):
fade_out()

func fade_in():
var tween = get_tree().create_tween()
tween.tween_property(rich_text_label, “modulate:a”, 1, fade_duration)
tween.play()
await tween.finished
tween.kill()

func fade_out():
var tween = get_tree().create_tween()
tween.tween_property(rich_text_label, “modulate:a”, 0, fade_duration)
tween.play()
await tween.finished
tween.kill()

How about this one?
Instead of declaring an onready variable, I declared the RichTextLabel via unique name to keep the code simple. Also reusable tween variable.
The thing about tweens is that they start automatically after creation and they are also automatically killed upon being finished. No need for cleanup.

extends Control

var ready_to_fade_out: bool = false
var fade_duration: float = 1.0
var fade_tween: Tween

func _ready():
   %RichTextLabel.modulate = Color.TRANSPARENT
   fade_in()
   await get_tree().create_timer(fade_duration).timeout

func _process(_delta):
    if ready_to_fade_out and Input.is_anything_pressed():
      fade_out()
      await get_tree().create_timer(fade_duration).timeout

func fade_in():
   if fade_tween: fade_tween.kill()
   fade_tween = get_tree().create_tween()
   fade_tween.tween_property(%RichTextLabel, “modulate”, Color.WHITE, fade_duration)
   fade_tween.finished.connect(func(): ready_to_fade_out = true)

func fade_out():
   if fade_tween: fade_tween.kill()
   fade_tween = get_tree().create_tween()
   fade_tween.tween_property(%RichTextLabel, “modulate”, Color.TRANSPARENT, fade_duration)
   fade_tween.finished.connect(func(): ready_to_fade_out = false)
1 Like

I get an error message for both instances of this line:
fade_tween = get_tree().create_tween()

Value of type “Tween” cannot be assigned to a variable of type “Tweener”.

I’m very sleepy right now but will look closer tomorrow and update how it goes! Thanks a lot for taking the time to help out. I never imagined that a fade in fade out script for text would cause so much trouble! If it weren’t for you helpful forum users, I think I’d have given up on it!

I apologize, there was a small typo from me.
it should be var fade_tween: Tween
and I have corrected my response.
Tweener does not exist

1 Like

Wonderful, it’s working!
For a moment, I got worried. Oh no. I just learned about tweens, now there are tweeners as well? Where will this end? Haha. Glad it was just a typo.
Thank you for helping out. Really appreciate it!

No biggie and I apologize for potentially confusing you!
Tweens are amazing and your first step into introducing straightforward animation effects. You can always consult the documentation to see what you can do with that.

Be it a simple one-liner
create_tween().tween_property(node, "scale", 1.2, 0.5)
or even combining multiple tweens together (for example changing node opacity WHILE it is moving to a location)

Btw, i think you can even remove the get_tree() from your tween creation