Cute and Simple Dialog Box | Let's Godot

Поделиться
HTML-код
  • Опубликовано: 2 фев 2025

Комментарии • 486

  • @samlee5774
    @samlee5774 Год назад +26

    This is wild, i've been trying to do this ages but never thought to await resized. Thanks!

    • @draicor
      @draicor 9 дней назад

      I had a Sprite3D -> SubViewport -> PanelContainer -> Label, and I was resizing the subviewport size based on the label.size after chaging its text and didn't understand why I had to either await get_tree().process_frame to let a frame pass, or assign the label.size twice to the subviewport size, now I know why, it resizes each axis separately, interesting..

  • @ian8448
    @ian8448 Год назад +23

    If you want to be able to change the scale of the text box and it still to be in the correct position compared to who is saying it:
    In the textbox display_text() function when you set global_position.x and y multiply it by the scale.x or scale.y accordingly.
    ex: global_position.y -= (size.y + 24)*scale.y

  • @Vash_EXE
    @Vash_EXE Месяц назад +1

    I really appreciate these tutorials! I really like how you lay out all of your nodes and whatnot. Keep doing what you're doing buddy!

  • @Vash_EXE
    @Vash_EXE Месяц назад +7

    For anybody having issues with the NinePatchRect. Make sure when you're doing the Edit Region step that you're not resizing the box with the Orange Dots, but instead you're just clicking on the dotted lines and moving those. When you're done with the resize you should have a tictactoe board with dotted lines and the orange dots still on the edges of the Sprite.

  • @shirotheshiro1098
    @shirotheshiro1098 6 месяцев назад +8

    Awesome tutorial!
    In case anyone else's code gets hang between the 2 resize awaits your empty text box in the 2d environment is tall enough to fit multiple lines in your current font and font size combination so the first resize doesn't necessarily causes a resize in y axis which results in the hanging.
    Just make the empty text box super small and it should always result in a resize as long as there's a letter in the text.

    • @draicor
      @draicor 9 дней назад

      or await a single frame by doing -> await get_tree().process_frame

  • @ricanamvs3390
    @ricanamvs3390 Год назад +28

    I'm really liking your godot videos. Do you plan to continue the tutorials?
    Thanks from Brazil

    • @DashNothing
      @DashNothing  Год назад +13

      Thank you! Yeah, I'm working to get a video out every week

  • @mewithoutYou52
    @mewithoutYou52 7 месяцев назад +6

    For anyone whose text box is appearing on the top left corner of the scene instead of above the NPC, be sure you're passing the correct node's global_position into the start_dialog function in your scene. Since I was attaching it to an AnimatedSprite2D inside a scene instead of attaching it to a root node it wasn't seeing the NPC's position to pass to the text box.

  • @MTG-BuenosAires
    @MTG-BuenosAires Год назад +4

    Works Perfect! thank you so much, im new at gameDev and godot so this was super helpful !

  • @TheArsonistGamer
    @TheArsonistGamer Год назад +8

    Followed everything in half speed, did everything i THINK right, but when i run i get an error that states :Invalid set index 'interact' (on base: 'null instance') with value of type 'Callable'. (It highlights my onready function func _ready():
    interaction_area.interact = Callable(self, "_on_interact")

    • @sims_berner
      @sims_berner Год назад +5

      i hate that he talks so fast. these are great tutorials, but run so fast it's hard to keep up and understand what's happening.

    • @DashNothing
      @DashNothing  Год назад

      For anyone getting this error - make sure you get your interaction area node with @onready var interaction_area = $InteractionArea and that it's in your scene

    • @yxgen4
      @yxgen4 11 месяцев назад

      are you using godot 4? I had this error but I was using godot 3.5

  • @anonykat31
    @anonykat31 4 месяца назад

    I have learned so much just doing this along, a bit speedy but amazing tutorial !
    Thank you very much my project really needed this !!

  • @bluemelonstudio
    @bluemelonstudio 11 месяцев назад +2

    Thanks friend for sharing, your tutorials are amazing

  • @isabellealejar-lo8sw
    @isabellealejar-lo8sw 2 дня назад +1

    BY THE WAY!!! If anyone is facing troubles with this in godot 4.3 then youre doing it wrong! Make sure it right! Mine works perfectly so if yours doesnt, fix it!

  • @notoreofreakshake
    @notoreofreakshake Год назад +2

    instant sub, no hesitation. great video!

  • @DRUYD
    @DRUYD Год назад +6

    Great video, thanks!
    I had one small issue though, if the text is very short (less than 5 characters), it seems like the first "await resize" doesn't behave as I'd expect, I can't explain why, but it causes the text box to never go away. I fixed it by setting a min length to run that first resize
    if (text.length() > MIN_WIDTH):
    await resized
    If anyone knows of a better approach or can explain why this happens I'd be really happy to understand this better.

    • @niunnniu
      @niunnniu Год назад +1

      bro can you tell me your MIN_WIDTH value? i also meet this problem, i want to fix it

    • @DRUYD
      @DRUYD Год назад

      ​ @user-ih3jm1dk7d sure, I've set it to 5 and that seems to work for me. I don't fully understand the details of it though so you might need a different value. I hope it helps.
      edit: to clarify, MIN_WIDTH is not a great name for it, as it is minimum text length really. I've set it to 5, as in 5 characters.
      So, if the text is longer than 5 characters, then it does the "await resized", otherwise it skips it. I'm still unaware of the larger implications of this or the underlying reason, but so far I haven't had any issues. If you gain some insight let me know as I'm interested :)

    • @booba_game
      @booba_game Год назад +1

      Problem is in "await resized", because "resized" is a signal. And for example, if you have margin container, that is bigger than whats inside of it, it doesnt emit a signal and code doesn't go any further

    • @DRUYD
      @DRUYD Год назад

      @@booba_game that makes a lot of sense, I'll check this when I go back to my project and see how to clean it up so this behaviour is clearer.
      Thanks!

    • @Tech-ib6wg
      @Tech-ib6wg 11 месяцев назад +1

      I had the same issue. Regardless of the min width, this will also happen if two consecutive lines of text are the exact same length (same character count). I solved it by only awaiting when the dialog_lines[current_line_index].length() is different from the previous length (current_line_index - 1). Although this would not catch the scenario some of you described where the the text is less than the min width.

  • @NDragonGames
    @NDragonGames Год назад +4

    This video gave me headache :)
    But it worked at the end haha

  • @adriel993
    @adriel993 5 месяцев назад

    damn nice tutorial! short and straight to the point

  • @dhdr27
    @dhdr27 7 месяцев назад +3

    If I have the start dialogue und continue dialogue on the same button. The dialogue finished and starts immediately again. I try making a workaround with a timer and a var = chat_finished but it doesn’t work.

  • @ItzAstroTheNoob
    @ItzAstroTheNoob 11 месяцев назад +5

    Thx! this helped me a lot on my Indie game (even tho all the code gets me tired 😅)

  • @brensnorf
    @brensnorf 11 месяцев назад +2

    I'm having a slight issue if you have any ideas on how to help; one of the places i'm trying to use the dialogue manager in game is a menu that runs while the game is paused. while I’ve been able to find alternate solutions to the "needs to be unpaused" elements, queue_free() in specific is my final hurdle from what I can tell. (at least, I assume queue_free() only works when the game is unpaused... anyways, are there any alternatives to queue_free() that may work when the game is paused?

    • @DashNothing
      @DashNothing  11 месяцев назад +1

      I'm not sure, but you can try using free() instead of queue_free() as it doesn't wait until the next frame to free an object.
      But unfortunately, I think the bast course of action is to implement a custom time scale that will only affect specific nodes. It would work by multiplying their velocities, animation speeds, and whatever else needs to be paused, by a custom time scale amount. They eill effectively be paused, while your UI and audio will work like normal.

  • @sabajoglidze9823
    @sabajoglidze9823 9 месяцев назад +4

    great tutorial but i have problem when i call functon game crashes so i cant even see whats the problem any idea what could cause it?

    • @DashNothing
      @DashNothing  9 месяцев назад +1

      You get an error in the debugger window at the bottom center of Godot when a crash happens. You will see what caused it in red text.

    • @sabajoglidze9823
      @sabajoglidze9823 9 месяцев назад

      @@DashNothing godot crushes with game

    • @DashNothing
      @DashNothing  9 месяцев назад

      @@sabajoglidze9823 Oh that is not normal. Best you can do is report an issue on Github.

  • @smillbag97
    @smillbag97 11 месяцев назад +1

    Great tutorial. Thank you for all the help!
    One problem I ran into is continuing to the next line of dialogue. My NPC just sits there on the first line of dialogue and doesn't continue. 😢 E to interact works and the label disappears, I just cant di anything for that point on

    • @DashNothing
      @DashNothing  11 месяцев назад +1

      I'm not sure I understamd the problem. Does the first line text disappear, but the next one doesn't appear? What about the textbox? Can you make sure your current_line_index gets incremented by writing some print statements?

    • @smillbag97
      @smillbag97 11 месяцев назад

      @DashNothing the textbox and the first line of dialogue appear. However, the subsequent lines do not appear and the textbox is stuck above the NPC with the first line of dialogue. I will check the current_line-index tomorrow night and get back to you!

    • @zavtronesegodnya
      @zavtronesegodnya 11 месяцев назад

      How can I make a dialogue appear when I interact with an NPC?

  • @devon674
    @devon674 Год назад +5

    so totally just let this minutiae consume my entire evening but if anyone else is confused by this, I thought for a very long time my NinePatchRect texture wasn't working properly, and spent a ton of time trying to fix a problem that wasn't there: what I was doing was using the scale mode tool, instead of using select mode to click and dragon the corner of the Textbox margin container. if this saves everyone, don't be like me. if you use the scale mode tool, it makes it look like the NinePatchRect is refusing to tile and scaling instead and looks like shit. I had to finally stop the video at the exact right instant and actually LOOK at what mode the editor was in.
    anyway um, I will continue with the tutorial now haha.

    • @DashNothing
      @DashNothing  Год назад +1

      Oof I know that feeling

    • @willd2609
      @willd2609 8 месяцев назад

      yeah i have spent an hour just trying to figure out why mine isn't working. Would love to see the source code for this project DashNothing!

  • @looves132009
    @looves132009 Год назад +4

    I love following your tutorials! I just have one issue I'd love your advice on. The "[E] to interact" label still appears on top of my dialogue box. How can I make it so once I hit the interact input, the label disappears so I can read the dialogue box without the "[E] to interact" text appearing on top?

    • @DashNothing
      @DashNothing  Год назад +1

      Thank you!
      In your _input(event) function you'd get the label like $Label and call .hide() on it to hide it.
      In the _ready() function you would connect to DialogManager's dialog_finished signal and in the callback function call $Label.show() to show it again..

  • @godotology
    @godotology Год назад +5

    Very very good tutorial . Your work is next level .
    Can you make tutorial about scroll container in godot 4 ??

    • @DashNothing
      @DashNothing  Год назад +3

      Thank you. You can see a use of scroll contaimer in my newest video about keybinding, where we use it to get a scrollable list of buttons. Is there anything specific about it that you would like to see?

  • @heylavenderbee
    @heylavenderbee Год назад +3

    Thank you so much for this tutorial!
    There's only an error that I just couldn't fix...
    When you use the connect function in the DialogueManager, connecting 'text_box.finished_displaying' to '_on_text_box_finished_displaying', it just doesnt work for me
    This is the error message: Invalid get index 'finished_displaying' (on base: 'MarginContainer').
    I guess that means that it has something to do that I may wrote the name wrong or something.. but I really don't know, could you help?

    • @DashNothing
      @DashNothing  Год назад +1

      I'm glad you enjoyed the video!
      Check if your finished_displaying signal in text_box.gd is spelled correctly. It needs to be spelled the same in text_box.gd and in DialogManager.gd when you connect it.

    • @MudpuppyGames-zn2qw
      @MudpuppyGames-zn2qw Год назад +2

      after a LOT of trial and error, for me the problem was that the preload("the_text_box_location.scn") was not the actual MarginContainer with the script but a parent node, therefore it couldn't load the proper script because it was searching one node above it.
      to fix this, i made the branch with the TextBox and its children a seperacte scene and preloaded that scene instead

  • @MrMineCrafterKing
    @MrMineCrafterKing 2 месяца назад +1

    GREAT VIDEO that helped me a lot

  • @ianjameshouse
    @ianjameshouse Год назад +1

    This is amazing, thank you

  • @JackDaloots
    @JackDaloots Год назад +1

    Nice nostalgia from the water level of Mario 64 :D

  • @EliSprinkle
    @EliSprinkle Год назад +3

    A more in depth look at the test guy script would be appreciated! i followed the interaction manager and dialog manger videos and still a little bit confused.
    i see there is 2 signals on the test guy script for _on_interaction_area_body_entered and exited. i tried creating finding those signal in the node tab under the interactionarea object.
    where does the "InteractionLabel" come from??? is that a @onready var as well? much thanks!

    • @DashNothing
      @DashNothing  Год назад +1

      I didn't go in depth with it because I only wanted to demonstrate the text box, whereas the interaction system I left up to the viewer. That being said, the system I had for this video was a bit hacky, with the InteractionLabel being a singleton any object can reposition. All in all I wouldn't recommend it.
      But if you're interested, I recommend the interaction system from this video:
      ruclips.net/video/ajCraxGAeYU/видео.htmlsi=T55JLX8nxWCiYC2b
      It's a very flexible system and works well with the dialog system from this video.

    • @EliSprinkle
      @EliSprinkle Год назад

      i have all the scripts written up with no errors, it is the implementation i am having trouble with. i have DialogManger, InteractionManager, InteractionArea scripts and object all good to go.@@DashNothing

    • @EliSprinkle
      @EliSprinkle Год назад

      is there a way a better way i can contact you? i really wanna implement your way of dialog and im a inch away from getting it to work@@DashNothing

  • @draicor
    @draicor 19 дней назад

    this is beatiful!

  • @tomnom
    @tomnom 9 месяцев назад +1

    10:35 For me, after the last line of dialog, the text box doesnt dissapear and just starts over right again. How can i make it dissapear after using it?

    • @DashNothing
      @DashNothing  9 месяцев назад +1

      You probably have the same key to start and advance the dialog, so right after it gets dismissed it gets triggered again. You can call accept_event() at the end of the input function in the DialogManager to stop the event propagating further.

    • @tomnom
      @tomnom 9 месяцев назад

      @@DashNothing wow such a fast response! Thank you for your awesome tutorials and dedication!

  • @TurtleSensor
    @TurtleSensor 11 месяцев назад +1

    I'm not sure where I messed up, but I don't see the textbox UI appear? I added some prints and I can see it printing to console the text lines and responding to my taps

    • @yxgen4
      @yxgen4 11 месяцев назад

      it might be behind your current layer!

  • @jboadas
    @jboadas Год назад +5

    Nice tutorial, thanks.

  • @willd2609
    @willd2609 8 месяцев назад +2

    please please please post the source code for this. I have tried to follow the instructions pausing the video every few seconds and i can't get the dialog box to display correctly. I am sure it's one little checkbox somewhere but I can't see where.

  • @ddmp_er
    @ddmp_er Год назад +4

    thx for tutorial! i used this in godot 3.5 but i have some questions
    in code u use "await resized" in margin container but godot 3.5 don't have this method. what i can do?

    • @DashNothing
      @DashNothing  Год назад +4

      You can use yield(self, "resized") and it will work exactly the same. Hope that helps!

    • @ddmp_er
      @ddmp_er Год назад

      thanks! it's work@@DashNothing

    • @mgomezmunoz92
      @mgomezmunoz92 Год назад

      @@DashNothing I am using godot 3.5 and "custom_minimum_size" is not recognized, any idea?

    • @DashNothing
      @DashNothing  Год назад

      @@mgomezmunoz92 I think you can use rect_min_size

  • @nexpersonal5066
    @nexpersonal5066 5 месяцев назад

    As I expanded on it, I had a bunch of problems with this code skipping lines at random and a lot of bugs.
    But changing "_show_text_box" to be a "for each" that awaits for an input signal instead of having the input event call the function again got rid of basically all bugs

    • @DashNothing
      @DashNothing  5 месяцев назад

      @@nexpersonal5066 Interesting. So you changed it to calling the show_text_box func inside a for eaxh loop? I wouldn't think that would make a difference because the logic flow remains the same.

    • @nexpersonal5066
      @nexpersonal5066 5 месяцев назад

      @@DashNothing basically instead of having _show_text_box run once, then on the _input event call it again, I run a "for line in dialog_lines" inside of it, and in each loop await for a line_advanced signal, that is emitted in the input section, this fixes the issue of some dialog lines being skipped when chain calling the function (I implemented dynamic button generation in the chatbox for responses, and some responses spawned their own dialog boxes)

  • @conehead1750
    @conehead1750 10 дней назад +1

    I'm assuming Godot 4.3 is different from 4.0. I've followed the tutorial probably 10 times so far, and I always get the error "Invalid access to property or key 'finished_displaying' on a base object of type 'Node2D'".
    My troubleshooting has mostly just been trying to ensure the signal is actually being recieved by the singleton. Regardless, great video. I implemented your interaction system from a separate video and it works beautifully.
    Thanks!

    • @isabellealejar-lo8sw
      @isabellealejar-lo8sw 3 дня назад

      Can you help me with the await problem? It says unexpected "await" in my script
      Edit: NVM!! i just didnt put it in my func display text

  • @luckyknot
    @luckyknot 10 месяцев назад

    This tutorial was excellent, very well explained and enjoyable to follow along! I'm working on dialogues that have different branching. how would you go about adding conditions and in-game variables that can affect/be affected by dialogues, branching to a new line or entire new text? Maybe it's solvabe with a 2D array? so the first order would store the dialogue line, and the second order of the array would save a certain number of variables? it's seems that things can start getting a bit unmanageable though...

    • @DashNothing
      @DashNothing  10 месяцев назад +1

      Thank you!
      I thought about it, and even though this is off the cuff, this is the direction I'd go in:
      - No, don't use nested arrays because the nesting would go crazy even at a few branching options.
      - There are tools to visually edit dialogs or ones that use a scripting language made for creating text based games with branching paths. You can find these in the Godot asset library.
      - If you want to do a quick custom implementation because your use case isn't too complicated (and I respect that and would probably do the same), I'd make seperate array variables for each branch of the dialog. For the lines where there's a decision to make I'd use a dictionary with the reference to the lines array a choice will lead to. Example:
      var hello = [
      "Hey!",
      {
      text: "How are you?",
      choices: [
      {
      text: "Good",
      next: goodResponse,
      },
      {
      text: "Bad",
      next: badResponse,
      },
      {
      text: "ATTACK",
      condition: player.has_weapon(),
      func: aggro_target(player)
      }
      ]
      }
      ]
      var goodResponse = [
      "I'm glad!"
      ]
      var badResponse = [
      "Sorry to hear that"
      ]
      I'd love to try to make that work. Hope this helps!

    • @luckyknot
      @luckyknot 10 месяцев назад

      @@DashNothing Thanks for taking the time to reply and write this example, After thinking about it, as I have many text and branching, to make it easier to manage and edit I think that I will go with a Google Sheet, a tab will be a scene that contains all the dialogues for that scene. Each scene will have a column to jump to a relative row or ID in another scene if needed, so if I move a row (dialogue line) that contains a jump, the reference should not break as it´s relative. Then parse it all to a csv with the proper data, and import into the game as a List of Arrays. I'll give it more thought let's see, thanks again!

  • @sixsalt1406
    @sixsalt1406 11 месяцев назад +1

    Hello, so I noticed you didn't show how you made your interaction label class and subclasses, I was wondering if this was in a previous video?

    • @DashNothing
      @DashNothing  11 месяцев назад +1

      I made the tutorial for the label and thr whole interaction system here ruclips.net/video/ajCraxGAeYU/видео.htmlsi=maNwZcsNesei19qb

  • @lucaortolani6907
    @lucaortolani6907 11 месяцев назад +1

    Hi! Thanks for the tutorial!
    I get an error at runtime on the text_box script at line 23:
    label.text = text_to_display
    "invalid set index 'text' (on base: 'nil') with value of type 'String'"
    You know what the cause might be? Thanks

    • @DashNothing
      @DashNothing  11 месяцев назад +1

      Thanks!
      The error means that the label var is null. Check if you get the label correctly on the @onready var line. Either the path to the label or the label node name is wrong.

    • @lucaortolani6907
      @lucaortolani6907 11 месяцев назад +3

      Thanks for the reply. The problem was I was starting the conversation calling the dialogueManager from the _ready() function of a npc i created...@@DashNothing

    • @braxtonsdev9564
      @braxtonsdev9564 10 месяцев назад +1

      @@lucaortolani6907 had the same issue, thx for replying with fix

  • @GreedFeed
    @GreedFeed Год назад +2

    I’m confused. Where is that resized signal coming from?

  • @MattGoode1
    @MattGoode1 11 месяцев назад

    two questions:
    1 - you "await" the textbox resizing signal. Without awaiting, is it possible that the resizing process takes longer than a frame and the calculations below it will be incorrect?
    2 - please tell me this isn't your real typing speed because i had to pause this so often to follow along mentally and allow my little fingers to catch up

    • @DashNothing
      @DashNothing  11 месяцев назад +1

      Without awaiting it is guaranteed that the calculations will be incorrect. The resize happens on the next available frame after changing the position, so we have to await it.
      And no, I speed up the typing so the video isn't unnecessarily tedious lol

    • @MattGoode1
      @MattGoode1 11 месяцев назад

      @@DashNothing haha i see i see, thank you. this was a great vid.

    • @MattGoode1
      @MattGoode1 10 месяцев назад

      @@DashNothingOne more question as I've been trying to tweak this. at 0:22 the line "I shouldn't waste my energy before ..." has the word "before" appear on the first line, then moves the word to the second line since it's too long to fit on the first. I would like the word to just appear on the correct line to begin with. I tried adding newline characters
      to where the text should break to a new line, but then the display_text() function breaks when it awaits resizing (lines 30-31 in the video) and I'm not sure why. Any ideas how to make that change work?

  • @DIYGamer1981able
    @DIYGamer1981able Год назад +1

    Where do you put the InteractionLabel code? I know its an anutoload but I don't see it when its built and I'm having problems with my project.

    • @DashNothing
      @DashNothing  Год назад +1

      For this video I made a scene called InteractionLabel of type label and a script attached to it with a function to show and hide the label. Then I autoloaded that scene (you can autoload scenes as well as scripts which is quite nice).
      This approach isn't the best and I only did it as a quick and dirty way of getting the point across for the focus of this video, which is the dialog system.
      If you are interested in an easy and flexible interaction system that works with the dialog system from this video, check this out: ruclips.net/video/ajCraxGAeYU/видео.htmlsi=uiRgGisX6dkcqGpr

  • @bellehuberty9457
    @bellehuberty9457 8 месяцев назад

    Thank you so much for the free tutorial! Incredibly useful and easy to follow. Do you or anyone else in the comments have any advice on how we should add the dialogue to objects/scenes in our game? That part was glossed over a bit and I'm a noob who would like more information. Thank you!

    • @DashNothing
      @DashNothing  8 месяцев назад +1

      I used this dialog system in my interaction tutorial. Cgeck it out: ruclips.net/video/ajCraxGAeYU/видео.htmlsi=7se_B4-1Hp8oDC06

    • @bellehuberty9457
      @bellehuberty9457 8 месяцев назад

      @@DashNothing awesome, thank you again!!

  • @unconscious5630
    @unconscious5630 Год назад +1

    With long texts in my dialog the size.y after the two awaits only ever is 88, never greater, even if the text makes the box larger than that. This causes the text bubble to grow as more letters are added to it rather than stay the same size. Do you know why this could be happening?

    • @DashNothing
      @DashNothing  Год назад

      I experimented and I couldn't recreate your problem. Is the number 88 something you use in a different place (like MAX_WIDTH)? Also ehat version of Godot are you using?

  • @isabellealejar-lo8sw
    @isabellealejar-lo8sw 2 дня назад

    BY THE WAY I NEED HELP!!!
    I want to be able to speak to the npc if im in its area2d or something, idk how, no matter how far i am, pressing the dialogue button will always start the dialogue

    • @DashNothing
      @DashNothing  2 дня назад +1

      @@isabellealejar-lo8sw Check out the interaction system tutorial ruclips.net/video/ajCraxGAeYU/видео.htmlsi=h0dHr8lNFu_1E99J

  • @Jdaucfqluoess
    @Jdaucfqluoess 10 месяцев назад +1

    I love it, just implemented it in my game. Question anyone : how would you prevent the player to move during the dialog ? is there a way to capture the input event ?

    • @DashNothing
      @DashNothing  10 месяцев назад +2

      I implemented that feature in the follow up video to this one. Basically, I just call player.set_process(false) when the dialog starts and player.set_process(true) when it finishes.

    • @Jdaucfqluoess
      @Jdaucfqluoess 10 месяцев назад

      @@DashNothing tranks, I just looked the next video. Actually you check DialogManager.is_dialog_active at the beginning of _process.

  • @Sillymanthatwearsabanana5
    @Sillymanthatwearsabanana5 2 месяца назад

    wonderful tutorial! I'm trying to fix an error that says: "invalid get index '29' (on base 'String')", It let's the first line work, but then the ! breaks it I think, how to fix?

  • @TheTrueUnknownCoder
    @TheTrueUnknownCoder Год назад +1

    Great tutoriel! I haven't managed to make it work, evry time I run my code this error pops up:Invalid set index 'text' (on base: 'Nil') with value of type 'String'.
    Does anyone know how to fix this?

    • @DashNothing
      @DashNothing  Год назад

      Seems like you don't have a reference to the label when you try to set its text. You should get the label at the top of the script with @onready. Make sure the name is correct, as it is in the scene tree (in case you renamed it).

    • @TheTrueUnknownCoder
      @TheTrueUnknownCoder Год назад

      @@DashNothing I checked but still (also thanks for the quik answer)

  • @نور-س7ل2ص
    @نور-س7ل2ص 11 месяцев назад +1

    hello thank you so much for your video but the problem now is how to make that text shown up when i interact with characters i am still a beginner and i don't know how to do that

    • @DashNothing
      @DashNothing  11 месяцев назад +2

      I got a video for that too: ruclips.net/video/ajCraxGAeYU/видео.htmlsi=gaVv8iO0qUEoLaLk

    • @نور-س7ل2ص
      @نور-س7ل2ص 11 месяцев назад +1

      @@DashNothing thank you so much

  • @trenom
    @trenom Год назад +2

    what is the equivalent of the await keyword in godot 3.5? is it "yield()" ?

  • @Hwaz.17
    @Hwaz.17 5 месяцев назад

    10:47, Im getting an error saying function: agurment 1 should be "Vector2" but is "Vector3"

    • @DashNothing
      @DashNothing  5 месяцев назад

      @@Hwaz.17 i'm calling start_dialog from a Node2D node, so global position is a Vector2. Are you calling it from a Node3D, who's global_position is a Vector3?

    • @Hwaz.17
      @Hwaz.17 5 месяцев назад

      @@DashNothing im calling from a staticbody3d

    • @DashNothing
      @DashNothing  5 месяцев назад

      @@Hwaz.17 Yeah, but the dialog is meant to work in 2D, thus requiring a Vector2 for position. You can try to adapt it for 3D, but that's not super straightforward.

  • @aTMiSKaMPoTi
    @aTMiSKaMPoTi Месяц назад

    i have a issue of there i am using godot 4.3 and there is an error coppy of ur code and 30 lines on dialogemanager text_box.finished_displaying.conect(... its return the error and tells me the finished_display geting invalid acces

    • @aTMiSKaMPoTi
      @aTMiSKaMPoTi Месяц назад

      its tell me (Invalid call. Nonexistent function 'conect' in base 'Signal'.) when i try to connect to signal

    • @DashNothing
      @DashNothing  Месяц назад +1

      @@aTMiSKaMPoTi You misspelled it. Its connect with double n

    • @aTMiSKaMPoTi
      @aTMiSKaMPoTi Месяц назад

      @@DashNothing ty i fix it it was my bad but now i am trying to fix the size its seems too big for my view and i cant scale it

  • @rodneyyt-lf4rd
    @rodneyyt-lf4rd 10 месяцев назад

    Good vid, its working for the most part. For some reason, when i get to the sixth line in my seven line array, the textbox offsets to the bottom right, no longer accepts input to advance lines, and the text immediately displays all of itself instead of reading letter by letter. im not sure what to look at first to figure this out.

    • @DashNothing
      @DashNothing  10 месяцев назад

      There is a problem with short lines that block the text box because the label is not wide enough to trigger a resize. Could it be that ykur sixth line is only a few characters long?

  • @hirador3879
    @hirador3879 Год назад +2

    Useful and good tutorial. 👍

  • @HansMilling
    @HansMilling 2 месяца назад

    Great tutorial

  • @JM-tj5qm
    @JM-tj5qm 6 месяцев назад

    Your pixalated font and margins look nice and crisp while mine look blurry.

    • @DashNothing
      @DashNothing  6 месяцев назад

      Try putting the resize mode to viewport or canvas_items in project settings -> window

  • @JuanAndresMingrone
    @JuanAndresMingrone 3 месяца назад

    Great tutorial man!! thanks!!

  • @Byte_Hub
    @Byte_Hub Год назад +2

    Didn't work for me, using Godot 3.5 with equivalent methods

  • @lambilla14
    @lambilla14 Год назад +1

    So cool video! But it dont work in my project, it doesnt give me an error it just appear the first thext and then stop working.

    • @DashNothing
      @DashNothing  Год назад +1

      Shame you couldn't make it work, but I'm glad you enjoyed the vid

  • @cmrdgi
    @cmrdgi Год назад +1

    Hey! Thanks for the tutorial. I almost got it to work but I am getting the following error after the first line of text is displayed:
    Invalid get index '44' (on base: 'String'). line 44 is : label.text += text[letter_index]. I am a complete beginner at both Godot and programming at large, help would be really appreciated :)

    • @DashNothing
      @DashNothing  Год назад +1

      This means your letter_index is somehow becoming larger than the number of letters in the text, which shouldn't happen. Is this error happening at the end of displaying the first textbox or after you press the advance dialog button to go onto the next textbox?
      Check 2 lines down from where the error happens (if letter_index >= text.length()). Make sure you wrote >= and not >.
      Hope this helps!

    • @cmrdgi
      @cmrdgi Год назад

      @@DashNothing ( if letter_index >= text.length(): ) is written properly, and the error is happening at the end of the first textbox being displayed. I am now somehow also getting an error for the _on_letter_display_timer_timeout() function at (_display_letter()). I guess this is because it's calling back to the function causing the error..

    • @cmrdgi
      @cmrdgi Год назад

      well actually it is now displaying the first letter, then breaking at (_display_letter()) only

    • @DashNothing
      @DashNothing  Год назад +1

      @@cmrdgi Check your textbox's timer and make sure oneshot is enabled. Otherwise it will keep timing down and trying to display a letter when it shouldn't.

    • @cmrdgi
      @cmrdgi Год назад +1

      @@DashNothing omg, stupid mistake hahaha. Thanks so much for the help! Hope you have a great day :)

  • @thabeetle1288
    @thabeetle1288 5 месяцев назад

    Thanks for the great tutorial, im trying to make it so you can skip to the end of the dialogue when you press a button, i tried to just make the letter time really fast but that bugs out the audio, what other way can i do that?
    Thanks!

    • @DashNothing
      @DashNothing  5 месяцев назад

      @@thabeetle1288 Maybe you could stop the letter timer and just add the rest of the characters into the textbox immediately

  • @OpheliaTheVampire
    @OpheliaTheVampire 5 месяцев назад

    somehow my text just expands endlessly vertically

    • @thabeetle1288
      @thabeetle1288 5 месяцев назад

      you can try increasing the custom minimum size of the label

  • @sakthisridhar835
    @sakthisridhar835 Год назад +1

    Bro i had problem in show_label is non existence which is in base margine container help me bro to figure it out

    • @DashNothing
      @DashNothing  Год назад +1

      Post the error message and I'll try to help out.

    • @sakthisridhar835
      @sakthisridhar835 Год назад +2

      @@DashNothing bro thanks but i fix it thanks for replying bro ❤️

  • @achi3405
    @achi3405 3 месяца назад

    Good tutorial however, I'm confused on how you'd get the text box to disappear without the use of an area 2d, so after all lines by the character are said the text box disappears.

  • @lordofdarkness5505
    @lordofdarkness5505 3 месяца назад

    Im geting the error “Invalid set index ‘text’ (on base: ‘Nil’) with value of type ‘String’.” Is this because of a update that make this tutorial outdated or is it because I did something wrong?

    • @Nademtis
      @Nademtis 3 месяца назад

      The problem is that the label node might not be ready yet. and is therefore null
      a simple solution is to use call_deferred. in the show_tent_box() - might help you out. The best solution is probably to add another check/step, before display_text() that checks if label is ready/not null
      simple solution in show_text_box():
      get_tree().root.call_deferred("add_child", text_box)
      text_box.call_deferred("display_text", dialog_lines[current_line_index])

  • @FredHareon
    @FredHareon 4 месяца назад

    I am using Godot 4.3. The sprite of the box isnt resizing when I enter a text.

  • @volmerandrei34
    @volmerandrei34 2 месяца назад

    Hi @DashNothing!
    Thanks for the awesome tutorial-it’s been really helpful! I followed along and got the dialog system mostly working, but I’m running into a problem where only the first line of dialog displays. After pressing the key to continue, it just repeats the first line instead of moving to the next one. The dialog never progresses to the following lines.
    Here’s what’s happening:
    The first line of dialog shows up correctly.
    When I press the key to advance, the finished_displaying signal seems to be received as expected.
    But the next line never appears.
    I’d really appreciate any tips on how to troubleshoot this! Thanks again for the tutorial.

    • @volmerandrei34
      @volmerandrei34 2 месяца назад

      The first line displays correctly when I use text_box.display_text(dialogu_lines[0]) and when I press space it repeats the same line(as expected), but when I use text_box.display_text(dialogu_lines[1]) it never displays anything

    • @DashNothing
      @DashNothing  2 месяца назад

      @@volmerandrei34 It could be that your one key press advances amd closes the dialog. What if you add a thrid line? Would two lines appear before it ends? And will dialog_lines[1] appear correctly?
      Also, if you want me to have a look at your code you can post your issue on my Discord

    • @volmerandrei34
      @volmerandrei34 2 месяца назад

      @@DashNothing could it be because in my NPC script I added @export to the lines Array? I tried more stuff and ended up deleting the first dialog line in the lines Array and now it doesn't display the second line(now first)

    • @DashNothing
      @DashNothing  2 месяца назад

      @volmerandrei34 @export is not the issue

    • @volmerandrei34
      @volmerandrei34 2 месяца назад

      @@DashNothing I fixed it. I didn't want the text box to appear above the NPC but on the screen like UI so i added this lines offset_left = -Max_Width / 2
      offset_right = Max_Width / 2
      offset_bottom=-50. I changed them into offset_left = -Max_Width / 2+150
      offset_right = Max_Width / 2-150
      offset_bottom=-500 and now it works.

  • @falkherbig4394
    @falkherbig4394 Год назад

    Everything works great, but when I interact, the dialog box spawns at the origin of the scene. It doesn't seem the give the global position. This is the code:
    extends Sprite2D
    const lines: Array[String] = [
    "Hello World",
    "This is a test"
    ]
    func _process(delta):
    if Input.is_action_just_pressed("advance_dialog"):
    DialogueManager.start_dialog(global_position, lines)

    • @DashNothing
      @DashNothing  Год назад

      In a line before DialogManager.start_dialog(...) can you write print(global_position) and in the output see if the position is correct. It should be something other than 0, 0.
      If that is correct, the problem is probably within the dialog manager's start_dialog function where it sets the textbox's position.

    • @falkherbig4394
      @falkherbig4394 Год назад +1

      @@DashNothingOh, man. I am so stupid. I just forgot the line during 9:19 ...
      Thanks for the quick help👍 earned a sub

  • @cn7rls
    @cn7rls 4 месяца назад

    I get an error "invalid set index 'text' (on base:Nill) with value of type 'string'

    • @DashNothing
      @DashNothing  4 месяца назад +1

      @@cn7rls Sounds like you didn't get the label from the tree correctly in the @onready var label = $... line. Double check if the path and the name of the label is correct.

    • @cn7rls
      @cn7rls 4 месяца назад

      @DashNothing is there anyway to just display the dialog box in the scene? I tried, but I got confused

    • @cn7rls
      @cn7rls 4 месяца назад

      In a scene* like a message for player or something like that

    • @DashNothing
      @DashNothing  4 месяца назад +1

      @@cn7rls You can edit the text in the label in the editor, but then you can't display anything else and you have to remove a lot of the code that deals with displaying the text.

    • @cn7rls
      @cn7rls 4 месяца назад

      @DashNothing I saw a lot of typewriter tutorials but they all display all the text in one time and when I put a sound to it, it becomes so annoying. guess I'll try using the typewriter with a timer

  • @rebelape4257
    @rebelape4257 Год назад

    func _display_letter (): is giving me a "Standalone lambdas cannot be accessed. Consider assigning it to a variable." error

    • @DashNothing
      @DashNothing  Год назад

      Sounds like you're missing the keyword func in front of the _display_letter function to me

  • @hijumiyuki6738
    @hijumiyuki6738 3 месяца назад

    @DashNothing i seem to have a problem advancing my dialog, it desplays the text boc and first line no problem but dont want to go to the next line

  • @ssihanji6802
    @ssihanji6802 6 месяцев назад

    Very good video. What software do you use to create the text box sprite?

    • @DashNothing
      @DashNothing  6 месяцев назад

      @@ssihanji6802 Thanks. I used Aseprite

  • @Setsunai_FM
    @Setsunai_FM 4 месяца назад

    Hi, great tutorial! I have a question. Can you implement this with a localization system?

  • @CosmicKingEvol
    @CosmicKingEvol 10 месяцев назад +1

    I did this tutorial and my whole screen glitching up when it spawns.. :/

    • @CosmicKingEvol
      @CosmicKingEvol 10 месяцев назад

      would really love some help..please
      The code for the text box
      extends MarginContainer
      @onready var timer = $LetterDisplayTimer
      @onready var label = $MarginContainer/Label
      const MAX_WIDTH = 256
      var text = ""
      var letter_index = 0
      var letter_time = 0.02
      var space_time = 0.06
      var punc_time = 0.2
      signal finished_displaying()
      func display_text(text_to_display: String):
      text = text_to_display
      label.text = text_to_display

      await resized
      custom_minimum_size.x = min(size.x, MAX_WIDTH)

      if size.x > MAX_WIDTH:
      label.autowrap_mode = TextServer.AUTOWRAP_WORD
      await resized
      await resized
      custom_minimum_size.y = size.y

      global_position.x -= size.x / 2
      global_position.y -= size.y + 24

      label.text = ""
      _display_letter()

      func _display_letter():
      label.text += text[letter_index]

      letter_index +=1
      if letter_index >= text.length():
      finished_displaying.emit()
      return

      match text[letter_index]:
      "!", ".", ",", "?":
      timer.start(punc_time)
      " ":
      timer.start(space_time)
      _:
      timer.start(letter_time)
      func _on_letter_display_timer_timeout():
      _display_letter()
      Code for the Dialogue Manager.
      extends Node
      @onready var text_box_scene = preload("res://textbox.tscn")
      var dialog_lines: Array[String] = []
      var current_line_index = 0
      var text_box
      var text_box_position: Vector2
      var is_dialog_active= false
      var can_advanced_line = false
      func start_dialog(position: Vector2, lines: Array[String]):
      if is_dialog_active:
      return

      dialog_lines = lines
      text_box_position = position
      _show_text_box()

      is_dialog_active = true


      func _show_text_box():
      text_box = text_box_scene.instantiate()
      text_box.finished_displaying.connect(_on_text_box_finished_displaying)
      get_tree().root.add_child(text_box)
      text_box.global_position = text_box_position
      text_box.display_text(dialog_lines[current_line_index])
      can_advanced_line = false


      func _on_text_box_finished_displaying():
      can_advanced_line = true


      func _unhandled_input(event):
      if (
      event.is_action_pressed("advance_dialog") &&
      is_dialog_active &&
      can_advanced_line
      ):
      text_box.queue_free()

      current_line_index += 1

      if current_line_index >= dialog_lines.size():
      is_dialog_active = false
      current_line_index = 0
      return

      _show_text_box()

      Just..why would my whole screen be glitching up. Any help, I would be very thankful of.

    • @DashNothing
      @DashNothing  10 месяцев назад

      @@CosmicKingEvol Well that's new. How exactly is it glitching up? What do you see?

    • @CosmicKingEvol
      @CosmicKingEvol 10 месяцев назад

      @@DashNothing actually, it appears to ber something to do with the forward+ thing and not with your code, so sorry for my mistake. It happening after adding the dialogue code was coincidence.

  • @kent8547
    @kent8547 Месяц назад

    First of all, awesome tutorial! Short and to the point, very nice :)
    I noticed when the camera is scrolling, the text sort of "jiggles" around a little bit. Is there a way I can fix this?

    • @DashNothing
      @DashNothing  Месяц назад

      @@kent8547 Try setting the stretch mode to viewport in project settings -> window

  • @Flumbingus
    @Flumbingus 10 месяцев назад

    love this style of game dialog! but I was wondering if you knew a way to incorporate bbcode into the text? changing the label into a richtextlabel works and everything but I don't want the bbcode to be printed in the textbox along with the dialog, do you know if there's a way to make it skip the bbcode syntax so it doesn't get printed out?

    • @DashNothing
      @DashNothing  10 месяцев назад +2

      Thanks! I would have to look into it, but I'd say you'd have to add the open and close bbcode tags into the label before showing the first letter of the line. At the dame time you'd have to change the string in the lines array to remove the bbcode tags. Then if the letters get put in between the tags in the rich text label I imagine it would work.
      Sounds like a good topic for a video, I'll keep it in mind.

  • @LMach1
    @LMach1 8 месяцев назад

    Using Godot 4.2 I got this working. Very fun way of typing out text. However, I was hoping to add in a RichTextLabel to use BBCode. I tried a few things with mixed results. The best I could do is have a ColorRect over the label and the RichLabel on top. Does anyone know what would a good way to make RichLabelText work?

    • @DashNothing
      @DashNothing  8 месяцев назад +1

      I actually did figure out how to adapt the rich text label into this over on my discord. It's actually pretty simple. If you're interested join and shoot me a message and I'll point you to it.

    • @LMach1
      @LMach1 7 месяцев назад

      @@DashNothing Awesome, done and done. Thank you.

  • @gameswithzeta6779
    @gameswithzeta6779 6 месяцев назад +1

    Great tutorial, unfortunately, in my case, the box shows up, writes down the first character and stops.

    • @gameswithzeta6779
      @gameswithzeta6779 6 месяцев назад

      its only typing the first character and stops

    • @DashNothing
      @DashNothing  6 месяцев назад +1

      @@gameswithzeta6779 Could be an issue with the timer. I'd debug it's timeout callback, if it gets executed at all.

    • @gameswithzeta6779
      @gameswithzeta6779 6 месяцев назад

      @@DashNothing will check it out thanks

  • @fyofyoriosity2350
    @fyofyoriosity2350 6 месяцев назад

    This is such a cool dialogue box! I am new to coding, and I am trying to replicate this in an earlier version of Godot our current project is running in, we can't use Godot 4, but 3.6 does not have the await functionality, and some other snippets throw an error - and signals confuse me. Does anyone know how to translate this code back one engine?

    • @DashNothing
      @DashNothing  6 месяцев назад +1

      @@fyofyoriosity2350Godot 3 uses a yield() function instead of await. The yield function takes in 2 params: object who's signal you're waiting for, and the signal name. So in this case it would look like yield(self, "resized"). Assuming resized is a signal in Godot 3, which I'm not sure about. Reference: docs.godotengine.org/en/3.5/classes/class_%40gdscript.html#class-gdscript-method-yield

    • @fyofyoriosity2350
      @fyofyoriosity2350 6 месяцев назад

      @@DashNothing
      #Thanks a ton! There are a few other things that don't parse correctly,
      #Can I ask about them as well? I'll try to leave a comprehensive list of all issues I encountered in case other Beginners 3.6 wants to follow~
      #Any help would be damn appreciated.
      #The yield seems to be fine now~ 3.5 however has the following issues:
      #SOLVED
      #signals are having slightly different syntax - instead of ( signal fnished_displaying() ),
      #leave the brackets away ( signal finished_displaying ).
      #Similarily, don't write ( finished_displaying.emit(), but (emit_signal("finished_displaying") ).
      #OPEN
      #3.6 does not allow the user to simply write size.x - it will throw an error, saying
      #size was not declared in the current scope. Is it the same as self.size.x?
      #SOLVED (But with question)
      #3.6 does not have await, use yield(self, "resized")
      #Do I have to use yield twice here too for both x and y?
      #OPEN/SOLVED?
      #custom_minimum_size.x does not exist - Should use rect_min_size.x instead?
      #OPEN
      #Okay, the autowrap mode line is where I absolutely found no way to solve it.
      #TextServer seems to be an addition to GD4? But it does not at all exist;
      #And while not throwing errors for autowrap_mode, it also does not suggest that
      #parameter, which means it might not exist? Only label.autowrap is suggested
      #(I have to reiterate that I am a noob and there is probably something i am overlooking)
      #What do I write instead of ( label.autowrap_mode = TextServer.AUTOWRAP_WORD )?
      #OPEN
      #global_position.x also does not exist - can I use rect_global_position.x instead?
      #OPEN
      #var dialog_text : Array[String] = [] does not work under any circumstance.
      #I suspect syntax, the godot 3.6 documentation writes something like var array = [insertstuffhere],
      #but as a beginner I have no clue how to translate parts from one definition to another
      #and which ones are important : ' D It is fine if I write var arr_dialog_text : Array = [],
      #But how do I definte that the inside of the brackets need to be String type?
      #Similar question for start_dialog(position : Vector2, lines : Array[String):
      #OPEN
      # .instantiate() is not a thing, should I use .instance()?
      #OPEN
      #text_box.finished_displaying.connect(_on_textbox_finished_displaying)
      #Throws an error. Even if the function is made, it said it doesn't exit.
      #Solution potentially:
      #Make it into a string? The error goes away, but idk if it would still work
      #text_box.finished_displaying.connect("_on_textbox_finished_displaying")
      #OPEN
      # text_box.global_position does not exist. Which other to use?
      # especially when calling the function DialogManager.func_start_dialog(global_position, lines)
      #does not work.
      #------------------------------------------ code -------------------
      #textbox script
      extends MarginContainer
      signal sig_finished_displaying_text
      onready var label = $MarginContainer/Label
      onready var timer = $LetterDisplayTimer
      const MAX_WIDTH = 256 #Textbox cannot be wider than this. Indicates line break.
      var text = ""
      var letter_index = 0
      var letter_time = 0.03
      var space_time = 0.06
      var punctuation_time = 0.2
      # ---- FUNCTIONS ---------------------------------------------------------------
      func func_display_text(text_to_display : String):
      text = text_to_display
      label.text = text

      yield(self, "resized")
      rect_min_size.x = min(self.size.x, MAX_WIDTH)

      if (self.size.x > MAX_WIDTH):
      print(label.autowrap_mode)
      label.autowrap_mode = true
      # = TextServer.AUTOWRAP_WORD
      yield(self, "resized") # wait for x resize
      yield(self, "resized") # wait for y resize
      rect_min_size.y = self.size.y

      rect_global_position.x -= self.size.x / 2
      rect_global_position.x -= self.size.y + 24 #to put text a little bit above the speaker

      label.text = ""
      func_display_letter()
      func func_display_letter():
      label.text += text[letter_index]
      letter_index += 1
      if letter_index >= text.length():
      emit_signal("sig_finished_displaying_text")
      return

      #If there are still characters to display:
      match text[letter_index]:
      "!", ".", ",", "?", ":":
      timer.start(punctuation_time)
      " ":
      timer.start(space_time)
      _:
      timer.start(letter_time)
      # ---- SIGNALS ---------------------------------------------------------------
      func _on_LetterDisplayTimer_timeout():
      func_display_letter()
      #------------------------------------------ code -------------------
      #DialogManager
      extends Node
      onready var text_box_scene = preload("res://scenes/ui/textbox/textbox.tscn")
      #var dialog_text : Array[String] = []
      var dialog_lines : Array = []
      var current_line_index = 0
      var text_box
      var text_box_position : Vector2
      var is_dialog_active = false
      var can_advance_line = false
      # --- FUNCTIONS ---------------------------------------------------------------
      func func_start_dialog(position : Vector2, lines : Array):
      if is_dialog_active:
      return

      dialog_lines = lines
      text_box_position = position
      func_show_text_box()
      is_dialog_active = true
      func func_show_text_box():
      text_box = text_box_scene.instantiate()
      text_box.finished_displaying.connect("_on_textbox_finished_displaying")
      get_tree().root.add_child(text_box)
      text_box.Position2D = text_box_position
      text_box.display_text(dialog_lines[current_line_index])
      can_advance_line = false
      func func_on_textbox_finished_displaying():
      can_advance_line = true
      func func_unhandled_input(event):
      if (
      event.is_action_pressed("ui_click") &&
      is_dialog_active &&
      can_advance_line == true
      ):
      text_box.queue_free()

      current_line_index += 1
      if (current_line_index >= dialog_lines.size()):
      is_dialog_active = false
      current_line_index = 0
      return

      func_show_text_box()
      #------------------------------------------ code -------------------
      #My Main from which I want to try seeing the textbox, no other controls
      extends Node
      const lines : Array = [
      "Hello World!",
      "Lorem ipsum odor et deo.",
      "This is test dialogue."
      ]
      # Called when the node enters the scene tree for the first time.
      func _ready():
      DialogManager.func_start_dialog(self.position * 3, lines)

  • @AnnieClaudeT1
    @AnnieClaudeT1 7 месяцев назад

    Hello, I encounter this error and I can't find why it does this : At :6.50, timer.start(punctuation_time), timer.start(space_time) and timer.start(letter_time) appear red and the error said:
    ""Error at (44, 17): Identifier ''timer" not declared in the current scope"
    I'm using Godot 4
    Thank you!

    • @DashNothing
      @DashNothing  7 месяцев назад

      Make sure you get the reference to the timer node at the top of the script with the line @onready var timer =$... putting the name of the timer node in your scene after the $.

    • @AnnieClaudeT1
      @AnnieClaudeT1 7 месяцев назад

      @@DashNothing Omg! That's it :D Thank you for the video and thank you for the fast answer! Have a nice day/evening!

  • @kacpereee8181
    @kacpereee8181 9 месяцев назад

    Hello, love the tutorials. I get en error on line 20 on textbox file. "Invalid set index 'text' (on base: 'Nil') with value of type 'String'.". I type everything as in video but it seems that when I use label.text I get nothing.
    The label var is set as @onready so there shouldnt be a problem

    • @DashNothing
      @DashNothing  9 месяцев назад +1

      Make sure that the path to the label after $ in the @onready line is correct. Seems like Godot couldn't find your label at the path you provided and instead returns null.

    • @kacpereee8181
      @kacpereee8181 9 месяцев назад

      @@DashNothing Yes, I tripple checked that in the first place. I even right clicked on the Label and copied its path to ensure that I don't make any typos. :/ Thats why I wrote the comment

    • @DashNothing
      @DashNothing  9 месяцев назад

      @@kacpereee8181 You can check what's stored in var label by writing print(label) in the _ready() func to see if it was fetched. If it is in there, but it's null when you try to assign text, it could be that the variable is changed somewhere in the code.

  • @MistForgeStudios
    @MistForgeStudios 8 месяцев назад

    Hello! really enjoyed the videos for the dialog and interact systems! I am running into an issue though. I have a test guy to interact with, he has line size of 4, and after i talk to him, after the second time I advance_dialog, it breaks and wont let me continue. I am not sure why this is happening. my dialog_lines.size() is 4 and my current line index is 2 when it happens. Also the text box changes location after I advance after the second box. Super confused and unsure on why this is happening and the solution. Been going through all the videos in regards to the dialog system and can't seem to find a solution to this... Any help would be awesome!

    • @DashNothing
      @DashNothing  8 месяцев назад

      How long is the third line, then one that doesn't get displayed? There is a problem with short lines because the two resized signals of the textbox don't get called.

    • @MistForgeStudios
      @MistForgeStudios 8 месяцев назад

      @@DashNothing third line is longer than the second line, the third textbox does show up but bugs out and changes location of previous textbox. But then I am unable to continue.

    • @DashNothing
      @DashNothing  8 месяцев назад

      @@MistForgeStudios I haven't encountered that so far. Are there any special characters in the third one? What if you switch the third and second line? Does it get displayed then?

    • @MistForgeStudios
      @MistForgeStudios 8 месяцев назад

      ​@@DashNothing Out of some strange trial and error, I commented out the line 25 - await resized, and now it works. I have no idea why that would make it work or why that would cause it to bug out. But yeah. it now works. weird. Also, thank you for the quick responses! :)

  • @dinox8vc46
    @dinox8vc46 Год назад +1

    why cant I find TextBox but only TextEdit and it doesnt work if i use TextEdit

    • @DashNothing
      @DashNothing  Год назад +1

      TextBox isn't a node right out of the box in Godot, instead you can use a Label node with a NinePatchRect node to make your own text box, just like in the video :)

    • @dinox8vc46
      @dinox8vc46 Год назад

      Thanks now it works, great tutorial!@@DashNothing

  • @zeroxxero5651
    @zeroxxero5651 11 месяцев назад

    Hey great Video!
    I followed along your Tutorial and managed to display the First Message, but the second message just pops up with the next text in a slightly different location and the scale from the previous text and doesn't want to advance further.
    I printed in the _unhandled_input(event)
    can_advance_line and is_dialog_active
    and can_advance_line seems to be at false and I don't understand why

    • @DashNothing
      @DashNothing  11 месяцев назад +1

      I noticed I get the same thing happening if the line is only one letter long. Is this the case for your second line?

    • @zeroxxero5651
      @zeroxxero5651 11 месяцев назад

      @@DashNothingIt was just one Test Word but after changing it to a whole sentence it works just perfectly now!

    • @DashNothing
      @DashNothing  11 месяцев назад +1

      @@zeroxxero5651 I found that changing the DialogManager's show_text_box function so can_advance_line is above text_box.display_text() line fixes this issue. So with that you can also have one letter lines (for example sometimes you'd like to just show "!").

    • @zeroxxero5651
      @zeroxxero5651 11 месяцев назад

      @@DashNothingyou're a hero! everything works fine now! thank you for your fast responses

  • @delqyrus2619
    @delqyrus2619 Год назад +4

    Nicely done. The only thing i would think of to improve it is to generalize the text timer/label(make it his own scene), so you can have coherent text behaviors between different types of displaying text. I have played a lot of games, where it was so annoying that different types of text ran with different speeds/behaviors...

    • @DashNothing
      @DashNothing  Год назад +3

      Great idea. That would also allow adjusting text speed in the settings.

  • @danbryandalisay8547
    @danbryandalisay8547 Год назад

    My solo npc dialogue its working fine but when i add another npc, both of them the dialogue are not working and not showing like pop up then disappear immediately 😞
    Sorry my for grammar 😅

    • @DashNothing
      @DashNothing  Год назад +2

      This happens because there is no check to see which npc is closer to the player before starting the dialogue, so both start it at the same time. You need to implement some sort of interaction system to handle interactions by distance to the player. Or you can check out my interaction system which works well with this dialogue system here ruclips.net/video/ajCraxGAeYU/видео.htmlsi=uiRgGisX6dkcqGpr

  • @lPandoraBox
    @lPandoraBox 11 месяцев назад

    Hello, so I have been messing around with ur script for a few days, and I have a question: Do u have any idea how I could make a animation on resize? I have no idea how to do it, already tried a lot of things, none of them seem to work...
    If possible I would like to contact u trough discord.

    • @DashNothing
      @DashNothing  11 месяцев назад

      I don't have a discord yet, but a popup animation for the text box is one of the things shown in the follow up video here: ruclips.net/video/QvkGnDNbLaQ/видео.htmlsi=JBMBSTvq2bDy8vsW

    • @lPandoraBox
      @lPandoraBox 11 месяцев назад

      @@DashNothing I know how to make a popup animation, my issue is: Imagine that one npc have 2 lines of a dialogue, right? When I want to change from one to another, I dont want to make another popup instead, I want to resize with an animation the current bubble

    • @lPandoraBox
      @lPandoraBox 11 месяцев назад

      @@DashNothing and ty for the answer btw

  • @m1chael_dev
    @m1chael_dev Год назад +1

    Its a really neat tutorial. Do you know how this can be implemented for 3d games? Thanks

    • @DashNothing
      @DashNothing  Год назад

      To display the text box in 3D you could use the Sprite3D node and assign it a viewport texture to render a viewport with the UI. Here's an example for Godot 3.5, but the general method is the same for Godot 4: godotengine.org/asset-library/asset/127

  • @TheMxxji
    @TheMxxji 5 месяцев назад

    hey man good video, also followed your interaction system video and it worked flawlessly. but for this one I've had a small issue. the dialog works fine however if I want to add another line of text then the first line runs fine but when i advance dialog it crashes the game (not godot just the game) and gives the following error:
    "Attempt to call function 'queue_free' in base 'previously freed' on a null instance."
    and it points to the "text_box.queue_free()" line in the DialogManager script. Any idea how to fix this? Thanks!

    • @DashNothing
      @DashNothing  5 месяцев назад

      @@TheMxxji For each line of text a new text box is created. Your error suggests you somehow tried to use the same textbox twice. There is an example of using the dialog manager for multiple lines in the video, where I create the NPC. Passing in the array of strings eorks.

  • @Cool_Kid95
    @Cool_Kid95 Год назад +29

    Godot?! LIKE ACE ATTORNEY?!

    • @DashNothing
      @DashNothing  Год назад +9

      Not quite haha

    • @turquoiseninju7
      @turquoiseninju7 Год назад +2

      Heh, even I was thinking of him when I first heard of Godot.. turns out the creators named the program kind of as a reference to him

    • @fu_games
      @fu_games 9 месяцев назад

      could you explain it to someone who never played ace attorney? what is the reference here?

    • @isabellealejar-lo8sw
      @isabellealejar-lo8sw 5 месяцев назад

      ​@@fu_gamesit's a character from ace attorney

    • @kenonerboy
      @kenonerboy Месяц назад

      No like what ill godot o your mum if u dont do your homework

  • @legoreptyle1048
    @legoreptyle1048 10 месяцев назад

    Hello! I'm trying to make your dialogue but when I start it, the only letter that display is the first one. I typed "text" and it wrote "t". Can someone help me pls?

    • @DashNothing
      @DashNothing  10 месяцев назад

      Is the timer getting set after every letter? Its timeout callback is what makes new letters appear.

    • @legoreptyle1048
      @legoreptyle1048 10 месяцев назад

      @@DashNothing I fixed it but if I press space after the end of the dialogue it keeps looping. Why?

    • @DashNothing
      @DashNothing  10 месяцев назад

      @@legoreptyle1048 It could be because the same key is for starting a dialog and advancing lines. In the dialog manager you can call accept_ecent in dialog manager's _input() function to eat the input. Let me know if this helps.

  • @DynamicccDrive
    @DynamicccDrive 8 месяцев назад

    Hi, a very cool video. only one thing I didn't understand is how to make the interact button appear when approaching a character? I don't understand where it is located in the code. and is there any other way to make the main character unable to move during the dialogue? so that he just stood in place, and at the end of the dialogue, the control appeared again?

    • @mimivrc4148
      @mimivrc4148 8 месяцев назад

      it's a different video ruclips.net/video/ajCraxGAeYU/видео.html

    • @DashNothing
      @DashNothing  8 месяцев назад +1

      The interaction is from this video: ruclips.net/video/ajCraxGAeYU/видео.htmlsi=payF90S3z1uuS9xS
      And stopping the player is in the textbox followup: ruclips.net/video/QvkGnDNbLaQ/видео.htmlsi=izBc9pxv88t2qBEw

    • @DynamicccDrive
      @DynamicccDrive 8 месяцев назад

      @@DashNothing спасибо, обязательно попробую 👍

  • @aidenquinn3329
    @aidenquinn3329 9 месяцев назад

    Awesome tutorial but I have a question. I did type in both the codes being the textbox and the dialogue manager but now I'm stuck. I know you made a practice dude to print it out but I'm trying to make it so that the textbox immediately starts when the level loads so I tried to do a "func _ready():" but after that I'm completely lost. I placed the code in the textbox itself as well and that also doesn't seem to work.

    • @DashNothing
      @DashNothing  9 месяцев назад

      Don't change the textbox or the dialog manager scripts - they work as is. Make a new scene that you want to be "talking" at the start of the game, define some lines in its script, and in the _ready() func call DialogManager.start_dialog, as shown for the NPC example in the video.

    • @aidenquinn3329
      @aidenquinn3329 9 месяцев назад +1

      Thanks man, definitely deserving of a sub dude.

    • @aidenquinn3329
      @aidenquinn3329 9 месяцев назад

      @@DashNothing Ok I set it up in a different project, did everything in the video and here's the thing. I have a character2d which has some vanilla movement code with the "const lines: Array[String] = ["hey wanna spar",]" at the top and the "func _ready():" beneath with the only line of code being "DialogManager.start_dialog" but its still not doing anything. am I supposed to place the textbox in the world itself because when I do that I get the box but no text. sorry if this is a hassle to read through because I've tried everything to get it to work and nothing has shown me progress yet.

  • @shanekammerman9583
    @shanekammerman9583 8 месяцев назад

    Why is it "global_position.x -= size.x / 2" and not "global_position.x = size.x / 2". I'm not sure I understand why its "-=". Thanks!

    • @DashNothing
      @DashNothing  8 месяцев назад +1

      We are taking away half of the width of the textbox from its global position to center it. If you didn't have that - there (and feel free to try this in Godot) you would just be setting the textbox's position coordinate to half of its width. This makes no sense and your textbox would be somewhere in the upper left corner of the screen.

    • @shanekammerman9583
      @shanekammerman9583 8 месяцев назад

      @@DashNothing Ohhhhh! Thanks so much for the explanation and the great tutorial!

  • @Technobote
    @Technobote 6 месяцев назад

    Hello thanks for the tutorial, that was really good. But do you know how to put it in a 3d scene?

    • @DashNothing
      @DashNothing  6 месяцев назад +1

      @@Technobote You'd have to use a quad mesh and a viewport texture to render the 2D elements (textbox) onto it.

    • @Technobote
      @Technobote 6 месяцев назад

      Thanks

  • @florantheplant
    @florantheplant Год назад +1

    At the end, you show a script of how to have a reference to DialogManager. But I don't know how to do the @onready for DialogManager correctly. How did you write it?

    • @DashNothing
      @DashNothing  Год назад +2

      In the beginning I went to Project settings -> Autoload and loaded the DialogManager.gd script.
      This makes it available in all scripts in your project, so you don't need to load it with @onready, just call DialogManager from anywhere. You'll know you set it up correctly if Godot gives you autocomplete suggestion for DialogManager when you start typing.
      Hope that helps!

    • @DashNothing
      @DashNothing  Год назад +2

      @@vindhyaganti9738 You can see the whole DialogManager script in the video. My commenz above didn't include a link, but RUclips recognized the words DialogManager(dot)gd as one. Sorry for the confusion :)

    • @vindhyaganti9738
      @vindhyaganti9738 Год назад +2

      @@DashNothing Thank you so much! Just finished the tutorial, but when I try to add the "DialogManager.start_dialog(global_position, lines)" to my player script, I get the error that "lines" is not declared in the current scope. How do I resolve this?

    • @DashNothing
      @DashNothing  Год назад +1

      @@vindhyaganti9738 Make sure your var lines is declared at the top of the script, along with your other variables. This way all functions will have access to lines. If you declared lines inside a function, other functions will not be able to use it

  • @aidenquinn3329
    @aidenquinn3329 9 месяцев назад

    I got the textbox to work but now I want it to spawn under the player when I enable it, is there any way of doing this. Until than Imma just keep trying till it works.

  • @Nina-wb8qb
    @Nina-wb8qb 6 месяцев назад

    im very new to all of this, how exactly do i make this npc and add the text to it and activate it...

  • @jasonozolins8781
    @jasonozolins8781 11 месяцев назад

    When I go to test it I keep getting the error "Invalid get index '47' (on base:'String')", not sure where I went wrong. Any help would be appreciated. I checked timer to make sure it was set to one shot, and the code was written correctly (I think) as suggested to someone else experiencing this issue. However, it is still crashing with that error message.

    • @DashNothing
      @DashNothing  11 месяцев назад

      Well it seems that your line has 47 characters, and the code tries to get the 48th character which doesn't exist. Func _display_letter() increases this index, and it should never reach a value larger than the string length because of the if letter_index >= text.length(), which is followed by a return statement. Can you post this part of your code here?

    • @jasonozolins8781
      @jasonozolins8781 11 месяцев назад

      @@DashNothing
      func _display_letter():
      label.text += text[letter_index]
      letter_index += 1
      if letter_index >= text.length():
      finished_displaying.emit()

    • @DashNothing
      @DashNothing  11 месяцев назад +1

      @@jasonozolins8781 So you're missing a return after finished_displaying.emit(). Check the vid at 6:12

    • @jasonozolins8781
      @jasonozolins8781 11 месяцев назад +1

      @@DashNothing Thanks so much! That fixed it. I appreciate the help.