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.
Not a Question. Just helping... :)Abdul Hannan AhmedFor all you guys who have been stuck on the 2nd Challenge. Here's how I tackled it!
What you basically have to do in the 2nd Challenge is to create an array of the dialogue items as a separate resource.
I'll show you how to do it step-by-step:
STEP 1: Create a new Resource (it is explained previously how to create a new Resource in Godot by GDQuest)
Here's how I created one:
```gdscript
extends Resource
class_name ChallengeResource
@export var array_of_items: Array[SlideShowEntry]
```
STEP 2: You have to modify the dialogue_items as:
`@export var dialogue_items: ChallengeResource`
And, in the `show_text()` function, modify the current_item to:
`var current_item := dialogue_items.array_of_items`
STEP 3:
Change to data for the expression, character and the text to:
`rich_text_label.text = current_item[current_item_index].text`
```gdscript
expression_texture_rect.texture = current_item[current_item_index].expression
body.texture = current_item[current_item_index].character
rich_text_label.text = current_item[current_item_index].text
```
STEP 4:
Change the `text_appearing_duration` to:
`var text_appearing_duration := (current_item[current_item_index].text as String).length() / 30.0`45Aug. 05, 2024
Stuck on the 2nd challenge pikminfan71I how are you doing? I've been trying to wrap my head around the 2nd challenge for way too much time and I'd love to see how the challenge is completed so I could understand what the task is. Thank you so much for everything!192Jul. 19, 2024
Explict typing versus relying on inferring typessteel_jokersIn this lesson, when we had reached the point where we preloaded defaults textures for the created resource, the lesson suggested removing the explicit type hint (Texture) and replacing it with the shorthand version; thereby allowing Godot to infer the type instead. In the spirit of the lesson's namesake, Stronger guarantees, would it not be more type safe to explicitly define the type? Could relying on inferring types lead to heavier cognitive loads in deciphering the code at a later date?
I understand functionally there is little difference, but I'm wondering if you have any experiences you could share on preferences for one over the other.
Is there a performance hit to explicit typing vs inferring or would you consider this a micro-optimization?
Would you choose to apply explicit typing in a large project and favor inference in smaller projects?
Do you feel this is more of a quality of life decision? (e.g. decreased typing, code noise, etc.)
52Jul. 17, 2024
About performance and typesliuti_devRecently I saw a tweet from one of the developers of Godot saying that strong types makes your code perform a lot better. My question is: does it work the same if you are inferring the type with the := operator?21Jul. 13, 2024
The 2nd Challengeilliterate-spider2nd challenge was very confusing i got stuck at some parts but read through the messages and got help and completed it.
I do have a question though. So basically in this case(or all cases) Resources from resource scripts are instances that can instantiated into the inspector specified properties then the Resource(instance/.tres file) can be deleted since its in property already.
Hope this is isnt confusing from my explanation. 20Dec. 05, 2024
Question about accessing the Array[ShoppingEntry]◆ LPIn the practice, I was thinking of accessing it's properties using something like items_list[item].text, but I saw in the answers project that we can directly access them using item.text & same for amount & price.
I can't seem to understand that. I thought the item in the for loop is the current index for the array, through which we could access the properties from ShoppingEntry.10Nov. 30, 2024
Challenge 2. Solution and questionPurpleSunriseHello,
I completed challenge 2. I had to look at the hints as I didn't understand the reason why you would group the conversation into one resource. You still have to edit each element in the inspector, but I guess it would be handy because you can save the conversation as a single resource and reuse it?
Anyway what I did is creating a new script that inherit resource.
In the script I set the class_name as suggest and I exported a variable which takes an array of [SlideShowEntry] resources. I called this conversation. Then I modified the dialogue_items var in slideshow_dialogue : SlideShowData (Is this how you normally do when you export a variable without any value?)
I then changed the current_item in show text to keep the index of the array inside slideshow_dialogue
I kept everything else as it was and it worked.
To quit the game I changed the the expression to compare the current_item_index with the size of the array in SlideShowEntry.
Here's the code!
```gdscript
extends Control
## an array of slideshow entries. It stores the SlideShowEntry resource instances.
@export var slideshow_dialogue: SlideShowData
var current_item_index := 0
## UI element that shows the texts
@onready var rich_text_label: RichTextLabel = %RichTextLabel
## UI element that progresses to the next text
@onready var next_button: Button = %NextButton
## Audio player that plays voice sounds while text is being written
@onready var audio_stream_player: AudioStreamPlayer = %AudioStreamPlayer
## The character
@onready var body: TextureRect = %Body
## The Expression
@onready var expression_texture_rect: TextureRect = %Expression
func _ready() -> void:
show_text()
next_button.pressed.connect(advance)
## Draws the current text to the rich text element
func show_text() -> void:
# We retrieve the current item from the array
var current_item := slideshow_dialogue.conversation[current_item_index]
# from the item, we extract the properties.
# We set the text to the rich text control
# And we set the appropriate expression texture
rich_text_label.text = current_item.text
expression_texture_rect.texture = current_item.expression
body.texture = current_item.character
audio_stream_player.stream = current_item.voice
# We set the initial visible ratio to the text to 0, so we can change it in the tween
rich_text_label.visible_ratio = 0.0
# We create a tween that will draw the text
var tween := create_tween()
# A variable that holds the amount of time for the text to show, in seconds
# We could write this directly in the tween call, but this is clearer.
# We will also use this for deciding on the sound length
var text_appearing_duration: float = current_item["text"].length() / 30.0
# We show the text slowly
tween.tween_property(rich_text_label, "visible_ratio", 1.0, text_appearing_duration)
# We randomize the audio playback's start time to make it sound different
# every time.
# We obtain the last possible offset in the sound that we can start from
var sound_max_length := audio_stream_player.stream.get_length() - text_appearing_duration
# We pick a random position on that length
var sound_start_position := randf() * sound_max_length
# We start playing the sound
audio_stream_player.play(sound_start_position)
# We make sure the sound stops when the text finishes displaying
tween.finished.connect(audio_stream_player.stop)
# We animate the character sliding in.
slide_in()
# Finally, we disable the next button until the text finishes displaying.
next_button.disabled = true
tween.finished.connect(func() -> void:
next_button.disabled = false
)
## Progresses to the next slide.
func advance() -> void:
# We increment the slide amount by 1
current_item_index += 1
if current_item_index == slideshow_dialogue.conversation.size():
# if we reached the last slide, quit
get_tree().quit()
else:
# otherwise, show the text
show_text()
## Animates the character when they start talking
func slide_in() -> void:
var slide_tween := create_tween()
slide_tween.set_ease(Tween.EASE_OUT)
body.position.x = get_viewport_rect().size.x / 7
slide_tween.tween_property(body, "position:x", 0, 0.3)
body.modulate.a = 0
slide_tween.parallel().tween_property(body, "modulate:a", 1, 0.2)
```
My question is, the utility of nesting an array of resources into a resource is because then you just have one resource that holds all the data you need for that dialogue for example? Or are there other reasons why you should do it? (I don't know, best practices, performance reasons, ease of use...). I am still metabolizing what I learned in this lesson. It makes sense if I think about it, but I would never came up with this challenge by myself and I want to learn what mindset I need to have when designing a code and then improving a code. The tip to always start from the simplest code is great but actually...
What is a simple code? Sorry for the wide range question.
What I mean is, this code looks simpler than actually having so many dictionaries in the script, and right now if I have to design a dialogue system, the first way to do it that will pop in my mind is this one. I am interested in understand what's the process that goes from having a dictionary to having an array of resources nested in a resource?
I am sorry if this confusing.90Nov. 09, 2024
Is there a difference between empty initialization and no initialization?CasimirMorelWhen creating the class
```gdscript
@export var expression: Texture = null
@export var character: Texture = null
@export var text := ""
```
you give default empty value.
Is there any difference with the absence of default value
```gdscript
@export var expression: Texture
@export var text: String
@export var character: Texture
```
?10Nov. 04, 2024
character classesOldManBradHi, in working through these classes, I started thinking through how I might handle a game that had 2-3 different characters. i.e. would I have a class for each character and that would cover everything about the character, including emotions, voice, etc. Then weapons might be a separate classes as well.
Not really a question here, but more so am I think about this in a way that makes sense long term?30Oct. 28, 2024
I’m not entirely sure in what context the 2nd challenge is gonna be useful…FioretinHmm…I’m trying to wrap my head around the second challenge. So basically you make a resource that contains all the dialogue items, right? It’s like…a resource that’s using another resource?
I’m guessing it’s supposed to be used if you’re making a text-heavy game like visual novels or RPGs? But why not just use the resource before this challenge?
Also, umm….If I’m understanding the 2nd challenge right…if, for example, someone is making a long visual novel and they’re splitting the text and dialogue into chapters. They can make a resource for each chapter (like class_name Chapter1, class_name Chapter2, etc), like that, right? That way they don’t have to mess with the codes that show and advance text. But wouldn’t that mean there’s gonna be a ***lot*** of class_names? Is there a way to do this without making it so global?
But also, I’m trying to complete the 2nd challenge by following the top comment here. So I did that, got an array of items in the inspector…and I don’t understand ***why*** it’s necessary. Like, it’s starts off empty, and clicking on it leads me to SlideShowEntry, at which point I’m like…why don’t I just use SlideShowEntry in the beginning? What‘s the point if it’s not so functionally different?
I wonder if I’m expressing myself properly here. It’s like…I ***sorta*** get how it can be useful but also ***not***…? Like, if after I make the ChallengeResource and then the dialogue in the Slideshow come pre-filled with all the necessary text and images *(like how I imagine it can work in the 3rd paragraph here)*, then I can see how it can be useful. In that case, it’ll be like, SlideShowEntry *(to make the stuff that you use to edit text and images in the Inspector)* -> ChallengeResource *(to write the text and determine which images to show)* -> Slideshow *(to show the whole dialogue/slideshow scene).*
But that’s not the case here.
So yeah. Right now I’m just really, really confused.
*(Also a part of me thinks that we’re using the word resource a lot in this lesson that I sorta get a confused about which context it means 😅)*20Sep. 12, 2024
I don't quite understand the meaning of challenge 2HazlarHello,
Congratulations for this course!
I can't visualize the meaning of challenge 2, maybe a gif, or an animation would clarify the issues better.
> "Imagine you want to reuse the slideshow scene, but you want to be able to load different conversations. How would you do that? "
The current design allows us to modify the words of each element.text of the characters, the precondition and to declare a variable of type Array of these properties. So to answer what I understood of the question, well I wouldn't change anything :D because the properties are already modifiable in the inspector.
After I tried to find another meaning when you say:
> "you should have one exported resource that contains all your dialogue items. "
So I thought I had to create a resource file where all the dialogue texts are listed, in the form of a text table ( `var scenario : Array[String] = [ [0] ="Hello, do you understand challenge 2?" , [1] = "no and you?" ]` ) is that it?
Thanks in advance70Sep. 03, 2024
Glossary: Editor Tooling typoTJHi! In the Glossary for 'Editor Tooling' (linked in the Recap section), there is a phrase with a missing word, leaving some mystery as to how to run the script:
`You can then run the script with <missing>.`10Sep. 03, 2024
Challenge 1: audio stream assignmentTJHi! To avoid an error, the last hint needs to be:
`audio_stream_player.stream = current_item.voice`
10Sep. 03, 2024
2nd challenge resource confusiontedious-crowI was initially confused as to how i would complete the 2nd challenge until I saw other Q&A solutions.
But now I am confused as to how i use this new system to set up a conversation.
in the inspector of the Slideshow node I see my dialogue_items variable with the SlideShowData resource. I click on it to see the array within SlideShowData and can add elements to it. but when i click on the element to add a resource it is completely blank.
I assume I now have to create resources that have info of different conversations but how do i make those resources? is each resource script its own array of dictionaries?
I guess my overall question is how do i use this new system to apply values to the body, expression, text and voice audio?
```gdscript
class_name SlideShowEntry extends Resource
@export var expression: Texture = preload("res://assets/emotion_happy.png")
@export var character: Texture = preload("res://assets/sophia.png")
@export var voice := preload("res://assets/talking_synth.ogg")
@export_multiline var text := ""
```
```gdscript
class_name SlideShowData extends Resource
@export var dialogue_item_array: Array[SlideShowEntry]
```
```gdscript
extends Control
#...
@export var dialogue_items: SlideShowData
var current_item_index := 0
#...
func show_text() -> void:
var current_item := dialogue_items.dialogue_item_array[current_item_index]
rich_text_label.text = current_item.text
expression_texture_rect.texture = current_item.expression
body.texture = current_item.character
audio_stream_player.stream = current_item.voice
#...
```20Aug. 29, 2024
Resource Smart Loading?back-fishHello! First of all, thank you for making such an in-depth learning resource. It's been a joy to work through.
I wanted to ask a question regarding how resources smart load. Since they share instances and only load in once, would setting up resources be a good way to create a game with character customization like in games such as Animal Crossing: New Horizons or Balder's Gate 3? Or would it run into the issue of all the items technically being loaded at once and hitting the performance?
Not an urgent question, mostly just curious how something like that would effect a customization heavy game.
Thanks!10Aug. 26, 2024
Need a breakdown of the 2nd challengeFernandoOk, I just spent 1h of my life in this challenge and the idea was to:
1 - Create a resource with the text, character, expression and voice
2 - Create a second resource that reads the first resource and put it in the scene
But I am really stupid and could not make this work in any way.
So, can anyone explain how they expected us to complete this challenge, I got curious ~~(and need answers)~~.70Jul. 17, 2024
L5.P1: Instructions and Code Test Out of Syncsteel_jokersThe instructions provided in the lesson for practice module (L5.P1) instruct us to edit the shopping_entry.gd to have the three properties: **name**, amount, and price
The practice code comments (and subsequent run check) are looking for the properties: **text**, amount, and price.10Jul. 17, 2024
Missing keyword in second challengeBob CornbobThe third hint is missing the var keyword.10Jul. 15, 2024
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.