Looks like you're not logged in

Login or Register to continue

Lesson Q&A

Use this space for questions related to what you're learning. For any other type of support (website, learning platform, payments, etc...) please get in touch using the contact form.

  • 2 tweens running at the same time.unhappy-dolphinHello there, When pressing the **next button** before the current tween finishes, another tween will play but it will not reset the visible_ratio as it will continue from where it stopped (e.g, visible_ratio = 0.6). This can be fixed using the from() method in the tween_property() method as the below code. However, since we are relying on the tween.finish signal for stopping the sound, the sound will stop before the last tween finishes due to the initial tween finishing time. I believe this can be solved if we can remove/free the current tween before goin to the next next text (i.e., immediately after pressing the next button), but I'm lost how to do this since the tween is a local variable in the show_text() function. Can I get some help on this? ```gdscript tween.tween_property(rich_text_label, "visible_ratio", 1.0, text_appearing_duration).from(0.0) ``` 6 7 Jun. 02, 2024
  • How I like to think about the text_appearing_durationCocaTo me is more intuitive to think about the text appearing duration as 'seconds per character' times the number of characters. So for example: text_appearing_duration = 0.05 * label.text.length() #0.05 seconds per character * total number of characters This way it adds 0.05 seconds the duration of the animation for each character. So you know how long it takes to show the next character, and texts of any size will show the characters at the same rate. 3 4 Oct. 16, 2024
  • Skip tweening when clicking the Next buttonThe_LunarianHi! I like to deviate a bit from the course when following one, so I decided to make it so you can "skip" the tweening on displayed characters when clicking the button. You'll see the full text, and then can click it again to go to the next entry. Like in o.g. Pokémon ! Here's the script. ```gdscript extends Control ## In characters per second. @export var text_speed := 15 ## Array of dialogue strings to be displayed in the label. @export var dialogue_items: Array[String] = [ "I'm learning about Arrays...", "...and it is a little bit complicated.", "Let's see if I got it right: an array is a list of values!", "Did I get it right? Did I?", "Hehe! Bye bye~!", ] var current_item_index := 0 var tween: Tween = null @onready var rich_text_label: RichTextLabel = %RichTextLabel @onready var next_button: Button = %NextButton @onready var background: ColorRect = $Background @onready var audio_stream_player: AudioStreamPlayer = %AudioStreamPlayer func _ready() -> void: background.visible = true show_text() func show_text() -> void: var current_item := dialogue_items[current_item_index] rich_text_label.text = current_item rich_text_label.visible_characters = 0 var text_length := rich_text_label.get_total_character_count() var text_appearing_duration := text_length / text_speed var sound_max_length := audio_stream_player.stream.get_length() - text_appearing_duration tween = rich_text_label.create_tween() tween.tween_property( rich_text_label, "visible_characters", text_length, text_appearing_duration ) var sound_start_position := randf() * sound_max_length audio_stream_player.play(sound_start_position) tween.finished.connect(audio_stream_player.stop) func _on_next_button_pressed() -> void: if tween and tween.is_running(): tween.stop() audio_stream_player.stop() rich_text_label.visible_ratio = 1 return current_item_index += 1 if current_item_index == dialogue_items.size(): get_tree().quit() else: show_text() ``` 1 3 Oct. 22, 2024
  • Buttons | Focus active only for keyboard/joypadandrea-putortiHey there, on a UI/UX design note, I find it ugly to leave the Focus active on the button I pressed with the mouse. Focus is useful for keyboard/joypad to know what you are selecting (opposite to mouse hovering), but I don't want it on when I use the mouse, because hovering is enough. How can I make so it only activates when I use a keyboard/joypad? It's ok if you only give me suggestions and I'll try to find a solution ^^ 6 3 May. 23, 2024
  • Another solution for the ChallengedavidakThis one is simple and effective: `var text_appearing_duration := 0.05 * current_item.length()` It uses half of a tenth second (0.05 sec.) for each character in the current text line. I think this speed matches the sound even better than the provided solution! I'm very happy with it. To make it more robust, it has to be limited to not be longer than the sound file, but for this simple practice, it works well. 1 2 Sep. 16, 2024
  • Why do some methods require parentheses(), while others do not?DargorTo stop the audio, we used "tween.finished.connect(audio_stream_player.stop)". I tried to use .stop() instead just to see if there was a difference, and I got the error "Trying to get a return value of a method that returns "void"". 5 2 May. 20, 2024
  • Do we have to clean up our tweens after we don't need them anymore?SingleMom420I tried Googling this question but it was mostly just people on Reddit arguing about the intricacies of RAM and stuff. I assume that for a project like these lessons, there's no need to worry about freeing tweens for performance reasons, but in general is it a good practice to manually remove tweens when they're no longer needed? If so, what's the best way to go about doing this? 1 2 May. 17, 2024
  • The GDQuest plugin is not marking L6.P2 as done even when it's workingAlphagold3I've got it doing everything it's supposed to but it doesn't wait for the text to finish displaying and the sound to finish playing before telling me that I didn't stop the audio stream. But then it stops at the right time. I'm not sure if this is a bug in the test or if I somehow did something wrong. My code is this: ```gdscript func _ready() -> void: rich_text_label.text = lines rich_text_label.visible_ratio = 0.0 var tween := create_tween() tween.tween_property(rich_text_label, "visible_ratio", 1.0, appearance_time) audio_stream_player.play() tween.finished.connect(_on_tween_finished) func _on_tween_finished() -> void: audio_stream_player.stop() ``` And when I run the test it thinks for a bit and then before the text finishes displaying it says it failed because the sound stream isn't stopping. However I'm listening to the sound and it's stopping properly when the text finishes appearing. I'm not sure what is going wrong here. 5 1 Dec. 18, 2024
  • My alternative solution for 'text_appearing_duration' challenge.MatejNot knowing (or remembering? 🤔) I could get a string length, I approached the challenge differently. ```gdscript var text_appearing_duration: float = log(rich_text_label.get_total_character_count()) / 2.0 ``` 1 1 Aug. 20, 2024
  • Different approach to the challengep_dev_Instead of the hints, I went with `rich_text_label.get_total_character_count() * 0.05`. It seemed to work. Are there drawbacks to this solution, comparing to the proposed way? 1 1 Jun. 16, 2024
  • challenge change length of dialogueMarcJNot sure if this was intentional or not but the challenge to change the length of the dialogue is also part of L12. 4 1 May. 14, 2024
  • feedback regarding help comments in the practice codecheeky chickpeaHi! I found that for me the comments inside the practice's code are too much help - these basically tell me what to do in which place in the code and remove the need to think about it on my own. I would very much like to take the practices to challenge me a little bit to remember what we just did and do it on my own. After all, if I need it, I can actually look it up in the code we wrote before anyway and in the checklist in the course here :) 1 0 Jun. 05, 2025
  • Type hint issue.LunaMoffI'm having the same trouble as another issue, but as far as I'm aware, I do have a type hint where I have the audio player defined. ``` @onready var rich_text_label: RichTextLabel = %RichTextLabel @onready var next_button: Button = %"Next Button" @onready var prev_button: Button = %"Previous Button" @onready var audio_stream_player: AudioStreamPlayer = %AudioStreamPlayer ``` these are my @onready vars, and the audio_stream_player seems like its typed correctly. But further down in the code, ``` var sound_max_offset := audio_stream_player.stream.get_length() - text_appearing_duration ``` is the line Godot has an issue with, I get an error stating "Cannot infer the type of "sound_max_offset" variable because the value doesn't have a set type." but wasn't the audio_stream_player typed as AudioStreamPlayer higher in the code? with the @onready variables? I'm a bit confused why I'm getting this error. 2 0 May. 31, 2025
  • Positive Tweening FeedbackLewlewI just wanted to let you know that creating the tween property for this RichTextLabel was the first time that I actually understood what I was doing. Maybe because the properties were really simple and it separated the steps of creating the Tween away from complicated and foreign concepts like the easing and the vectoring that I had my first Ah Ha moment with how a Tween is actually written. It also helped that I understood how to pull up the Tween documentation in the editor and use it to help me recall how it was supposed to be written. 1 0 May. 06, 2025
  • How to tween letter appearance?gnes_I imagine that to achieve that I'll need another approach instead of the `visible_ratio`, but: How can I tween the letter's appearance? So instead of instantly popping up on the screen, I'd like the letter to, once it's shown, to (independently) slowly 'unfade' (so change fade/opacity from 0->1). I've tried playing with `RichTextEffect` but couldn't really make it work. 3 0 May. 02, 2025
  • Alternative solution to use both audio filesgnes_Given we have two different audio files, I wanted to use both. So on the `AudioStreamPlayer`, instead of dropping the audio file to the `stream` field, click on the dropdown button of the field instead and you'll be able to select the resource. You can then select a new `Randomizer`, which will pick a random stream from the list of resource streams you provide. You can then drop both audio files in the `Streams` field and voilà. As an extra, to make it **really** random, change the `Playback Mode` from `Random (Avoid Repeats)` to simply `Random`. Given there's only two files, with the `Avoid Repeats` they'll play sequentially. Enjoy the noise. 1 0 May. 02, 2025
  • visible_ratio typo?DanIn the first “Try Answering This” question, there are two identical answers labeled “visible_ratio,” one of which is the correct answer and one of which isn’t. Unless I’m misreading it somehow? PS: I’m going through the course for the second time and y’all are right, the repeat helps a lot to solidify knowledge. Thank you for all your great work! 1 0 May. 01, 2025
  • I love the progress I'm making so far !CG_MuffinI've now done a few extra challenges without looking at the hints. (here is my version of this lesson's last challenge, don't know if its the best way to do it but... hey it works !): ```gdscript var text_lenght := rich_text_label.text.length() rich_text_label.visible_ratio = 0.0 var tween := create_tween() var text_appearing_duration := text_lenght * 0.1 tween.tween_property(rich_text_label, "visible_ratio", 1.0, text_appearing_duration) ``` I can't believe than in two weeks I've came from not having touched code in my entire life to being able to do those challenges by myself ! (oh, and pressing "." after a variable just to see the various methods available to its type is helping me a lot too lol). 1 0 May. 01, 2025
  • sound_max_length variable namingvladIt seems that `sound_max_length` variable in the examples doesn't represent maximum length of a sound. Rather it represents the maximum offset. Wouldn't it be better to call it something like `sound_max_offset` or `sound_max_start_position`? 1 0 Mar. 25, 2025
  • Random Questionsoft-mosquitoThis has nothing to do with the lesson, but I noticed when you hold shift + ctrl and then use your arrow keys, it selects multiple lines but also gives you multiple cursors that all type at the same time. What is the purpose of this? Sorry for taking up some time for real questions. 1 0 Jan. 23, 2025
  • Why isn't visible_ratio set to 0 before the text?KoreyIn the first challenge where we learn to set rich_text_label.visible_ratio and animate the text with the tween, why is `rich_text_label.visible_ratio = 0` configured after we set `rich_text_label.text = current_item`? Wouldn't that mean the text will still be present, if even for a moment until that setting applies? Or does this not matter because it's all being set within that single frame and the next one wouldn't show it because the property is now set? 1 0 Jan. 22, 2025
  • Clicking previous button while the first sentence is still appearingstraight-eagleHi, I find it weird when I try to clicking **previous** button while the first sentence is still appearing. I think it will stop appearing and the sentence that appears in half will disappear. And then the whole sentence will start appearing from the beginning. However, it does not stop. It still keeps appearing, but in a slower speed, which is weird. But if I wait until the whole first sentence is completed, then click the **previous** button, it will disappear and start over, which behaves as expected. ```gdscript extends Control @onready var rich_text_label: RichTextLabel = %RichTextLabel @onready var next_button: Button = %NextButton @onready var previous_button: Button = %PreviousButton @onready var audio_stream_player: AudioStreamPlayer = %AudioStreamPlayer @onready var budio_stream_player: AudioStreamPlayer = $BudioStreamPlayer var dialogue_items: Array[String] = [ "Paparboy, Paperboy🤗", "All about that paper💸, boy", "Paparboy, Paperboy🤗", "All about that paper💸, boy", ] ## Holds the index of the currently displayed text var current_item_index := 0 var text_appearing_duration := 0.8 func show_text() -> void: var current_sentence := dialogue_items[current_item_index] rich_text_label.text = current_sentence rich_text_label.visible_ratio = 0.0 var sound_max_length := audio_stream_player.stream.get_length() - text_appearing_duration var sound_start_position := randf() * sound_max_length audio_stream_player.play(sound_start_position) var tween := create_tween() tween.tween_property(rich_text_label, "visible_ratio", 1.0, text_appearing_duration) tween.finished.connect(audio_stream_player.stop) func _ready() -> void: show_text() next_button.pressed.connect(advance) previous_button.pressed.connect(goback) func advance() -> void: current_item_index += 1 if current_item_index == dialogue_items.size(): current_item_index = 0 show_text() func goback() -> void: current_item_index -= 1 if current_item_index == -1: current_item_index = 0 show_text() ``` 1 0 Dec. 26, 2024
  • i love the resultkazathis experience was amazing! you do an excelent job doing this course, i'm having so fun on that! 1 0 Dec. 19, 2024
  • First time completed!Joey_mc2This is liberating. Just finished L6. P2. and I did it on the first attempt with no mistakes and I didn't have to use hints for once! I know it isn't much code but it feels good to have written something for once without any 'help'... making progress and learning!! 1 0 Nov. 14, 2024
  • My approach to audio playingPurpleSunriseHello, By instinct I wanted to try to code the audio playing without looking at the tutorial first. I used a different approach to it and I wanted to know why would I choose one approach over another. Right now my show_text() looks like this and it works just fine: ```gdscript func show_text() -> void: var current_item := dialogue_items[current_item_index] rich_text_label.text = current_item rich_text_label.visible_ratio = 0.0 var text_appearing_duration := 1.2 var audio_max_lenght := audio_stream_player.stream.get_length() - text_appearing_duration audio_stream_player.play(randf_range(0, audio_max_lenght)) var tween := create_tween() tween.tween_property(rich_text_label, "visible_ratio", 1.0, text_appearing_duration) tween.finished.connect(audio_stream_player.stop) ``` Of course `randf() * audio_max_lenght` totally makes sense, I just wanted to know if I should favour a more math oriented way of thinking over another. Thank you! 1 0 Oct. 31, 2024
  • Typo - "that" missingCasimirMorelI'm not 100% confident, but I believe that a "that" is missing in the L6.P1 text "a task needs 10 minutes" should I believe be "a task that needs 10 minutes" 1 0 Oct. 23, 2024
  • Imitation of printingram876After practice, I had a question, but how can I play the animation speed in the entire animation at different speeds to simulate printing. I came up with this method. Tween announced at the beginning of the script, inside the show_text function I will recreate it. A timer node has been created, a function has been connected to its signal, and each time it is started, it has different values. The function that is linked to its signal then pauses, then starts tween. But isn't there a better way? Mine doesn't work quite right, in my opinion. ```gdscript func start_text(): if tween.is_running(): tween.pause() start.wait_time = randf_range(0.2, 0.3) else: tween.play() start.wait_time = randf_range(0.3, 0.4) ``` 1 0 Oct. 17, 2024
  • Split the animation of a specific lineram876Hi! My question is this: if I have conceived that in one place of the dialog I want a certain part of the text to be displayed first when clicking on the button, and then another part, then how to implement this? For example, "And the winner... number two!" Here I want to print "And the winner..." on the first click (here the animation stops), and on the second click the animation continues, and as a result we get the whole line: "And the winner... Number two!" I know that the animation has a pause, but it does not yet occur to me how to indicate that I want to pause the animation for this line in this part of the animation. 1 0 Oct. 17, 2024
  • Wrong solution gets a correct PASS on L6.P1CocaInstead of doing the correct solution which is: "tween.tween_property(rich_text_label,"visible_ratio", 1.0, appearance_time)" I did "tween.tween_property(rich_text_label,"visible_ratio", 1.0/appearance_time, 1.0)" and it said the solution was correct, even though it was very wrong. I did it this wrong way because I didn't understand correctly the "grow the visible ratio to 1 over appearance_time**" Lol** Btw I'm not native english speaker so it was ambiguous to me. 1 0 Oct. 14, 2024
  • Stream get_lengthIronEvaWhen reading the documentation of Stream: [https://docs.godotengine.org/en/4.3/classes/class_audiostream.html](https://docs.godotengine.org/en/4.3/classes/class_audiostream.html) It says '_get_length', but when I press the '.' after stream in the coding I am working with I get 'get_length' without the underscore at the beginning. From What I remember reading about "_" at the beginning means it's not supposed to be messed with by other coders (I could be wrong). Why is there no underscore in the one I did? This is probably a silly question, if so sorry about that. 1 0 Sep. 25, 2024
  • Typo in Section 'Playing the sound'TJHi! I'm just mentioning a small typo in the lesson, in the Section 'Playing the sound': Let's first **calcualte** 1 0 Aug. 10, 2024
  • Why current_item.length() / 30.0 ?miniature-gazellein the final challenge, i don't get why we have to divide by 30.0, or by any number for that matter 4 0 Jul. 20, 2024
  • L6.P1 Test Setup FailedThirtyOlives> Test setup failed. > There should be an 'lines' String. > There is no 'lines' String. Did you remove it? It's required for the practice to work. Hiya! My code seems to solve the practice lesson as intended. I'm not sure why the 'lines' variable isn't initialising correctly. I even tried changing type inference to specify that it was a String & the error was unresolved. Maybe something to look into. ```gdscript extends ColorRect @onready var rich_text_label: RichTextLabel = %RichTextLabel var lines := """ If you know that 6 Hours of debugging can save you 5 minutes of reading documentation If you try to automate for 10 days a task needs 10 minutes If you think, once again that you can finish in 1 hour a task that's always taken you 9 You'll be a gamedev, my student """ var appearance_time := 10.0 func _ready() -> void: rich_text_label.text = lines rich_text_label.visible_ratio = 0.0 var tween := create_tween() tween.tween_property(rich_text_label, "visible_ratio", 1.0, appearance_time) ``` Otherwise this has been a fantastic course & everyone else has already posted & solved anything more I could have asked in these sections. Thanks! 22 0 Jun. 21, 2024
  • Unexpected error: cannot infer typebeekI am using 4.2 on macOS. When I include the line: var sound_max_offset := audio_stream_player.stream.get_length() - text_appearing_duration It gives the error: Cannot infer the type of "sound_max_offset", and will not compile. But the line: var sound_max_offset:float = audio_stream_player.stream.get_length() - text_appearing_duration works totally fine. With some investigation it seems to be specific to the get_length() function.. 6 0 Jun. 20, 2024
  • How to stop the sound when pressing Backandrea-putortiHey there, I'm trying to make the script don't play the sound when pressing the Back button. I tried adding ```gdscript audio_stream_player.stop ``` in both func rewind() and in an If inside func show_text(), but it didn't work out. Any tips? 10 0 Jun. 19, 2024
  • L6.P1 - Fails if using get_tree().create_tween()RomanGnomeBelow _ready function fails in the code due to an `Out of bounds get index '1' (on base: 'PackedStringArray')` at line 47 of the `test.gd` file when running L6.P1. ```gdscript func _ready() -> void: rich_text_label.text = lines # Make sure to start the visible ratio at 0 # Create a tween, and grow the visible ratio to 1 over appearance_time rich_text_label.visible_ratio = 0 var tween = get_tree().create_tween() tween.tween_property(rich_text_label, "visible_ratio", 1, appearance_time) ``` If you change line 7 to `var tween = create_tween()`, the practice exercise succeeds. My question is, what's the difference between `get_tree().create_tween()` and just `create_tween()`? I see the documentation for `create_tween()` talks about how it's the same as the other however if calls a `bind_node(self)` automatically. 2 0 Jun. 18, 2024
  • Problem with first Exercisepikminfan71Hi I tweened the visible_property to 1.0, it works perfectly, but the exercise says I didnt? ill paste the code and would love some help. thanks! func _ready() -> void: rich_text_label.text = lines # Make sure to start the visible ratio at 0 rich_text_label.visible_ratio = 0.0 # Create a tween, and grow the visible ratio to 1 over appearance_time var tween : Tween = create_tween() tween.tween_property(rich_text_label, "visible_ratio", 1.0, 5.0) 3 0 May. 22, 2024
  • Audiofile caracteristics needed to play it randomly?SebHello, When I cut/paste music files in audacity, I always have to check carefully where I cut them to avoid unpleasant noises or to fade in/out the sound. So I found it a bit magical that you start anywhere in the audio file in the lecture. I tried to replace your file with a music file... and I got the usual bad noise. Does the file you provide have some kind of special sound structure that allows to jump start it from anywhere? (I don't know if my question is clear, I know nothing about music theory) 4 0 May. 19, 2024
  • Using a looping audiointent-mantisHello, As an alternative to calculating valid vs. invalid audio offsets, could you import the talking_synth.mp3 file with loop enabled? This way all offsets would be valid, and you would also have enough sound no matter how long the dialog was. I was wondering if there are any disadvantages to using this method vs the one in the lesson? 6 0 May. 16, 2024
Site is in BETA!found a bug?