Godot Dialogue System — Introduction / Tutorial

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hi so today i want to show you how you can start designing your own dialog system kind of like what you see here so the way i did this is i have an image here in the corner representing what npc you might be talking to at the time or maybe what object you're looking at then there's some text whatever the npc might be saying and then you have some options here where you can click on how you want to react to it if i take the last option here i can just close the window immediately i can spawn a new dialog in i can select this one and there comes a reply or i can select this one and there comes another reply and stuff like that you can link these together however you like and really make any size and complexity of a conversation now today i'm not going to go over how you can move these kind of things into a json file or how you can use any kind of fancy plugins there are some good dialogue plugins for the godot engine but for now i would rather stick to the basics and show you how you can do it inside the engine and we can go over alternative details later on so how do we implement this stuff first of all i made a folder here for my dialog system it contains some images which is the godot icon and my necromancer.png and it contains a font i'm just using it's technically a theme but all it has is the font in it so it looks a little bit better than the default font inside of godot this part isn't really necessary at all new scene test scene sure user interface so we have a control that is covering the entire screen let's give it a color rect so we have a background give it some grayish color that's a bit a bit more colorful maybe something like that and yeah this is essentially gonna be our background we are working in in reality there might be some game scene in the background maybe a 3d game or whatever it is really it doesn't matter but here since there's nothing else i'm just putting a background to make it a bit clearer what we're working with now what is our thing going to look like so what i think is going to look like is first of all i'm gonna make a control let's have it cover part of the screen instead of all of it i guess something like that and this is the area that's actually gonna be used by this so if i use a color rect again give it v for rect give it a darker color so we can tell it apart a bit and yeah this is essentially the entire dialog box so we want a section up here for the npc text and a section down here for player options so let's put a v box container here we can use the entire thing for now um i suppose to make it a bit prettier let's give it a bit of margins let's say 10 10 minus 10 minus 10 and then we want two control nodes in here one for the npc i'll just call it npc section and one for the player and let's give them some size flags so they actually take up the available space okay we still want to be able to see them so i'm again going to use a colorect it's just the easiest option to visualize exactly where control starts and ends so there we go we have these two sections built up a bit of a gap in between you can change the settings for that in here of course now let's build up the npc section it's going to need some space for an image like we had earlier so i'll just use a texture act for this it's going to need some space for text so i can just use a label for this and since we want these things to be next to each other i can use an hbox container drag the two in there and give them some size flags okay the hbox container is quite small right now let's see yeah that's better i guess this one doesn't really need the expand flags but yeah that should do keep it like that for now as a placeholder i'm just gonna drag in an image i don't really have to worry about the sizes of the different images because all of my images are 64 by 64 pixels as long as i keep that consistent i don't have to worry about this if you're not gonna keep that consistent you may wanna customize things a bit and make sure everything stays aligned properly now i'm gonna give this hbox container some margins again so the image isn't right in the corner and 10 minus 10 minus 10 that seems fine and this is where the text can go and just call this here text i can just call this here image and that should be fine now let's go in here and give this section another v box container because inside of this v box container which again for rectangles and yeah we don't need size flags but we do want to add some margins keeping it consistent so what's gonna go in here is a variety of buttons that can be clicked but since the number of buttons depends on exactly what we're doing with it i'm not going to be setting these right now i'm still going to apply my theme to this on theme put it in here and that should be fine that should apply to all the children so now we have this we can put some placeholder text here and everything is looking fine cool so how are we going to fill this stuff that's two things we want here and since we're inside this big thing here i'm just gonna add a button the same way we had in the preview scene earlier spawn dialog button something like that that spawn dialog i move this button over here and this button is going to be what i am using to spawn this dialogue in and make it visible and interactable and stuff but in reality you would probably instead spawn it in when you're talking to an npc interacting with an object something like that so i am giving this thing a script and this button is actually what's going to decide exactly what dialog is going to be visible so i don't want the dialog to be hard coded into this box here instead it's much simpler to once create this uh dialogue pop-up we can actually call it that and we can actually save this as a separate scene so if we save the save branch as scene put it back into the correct folder then it's a bit simpler now this is what we use and it kind of becomes its own thing we can open there so let's decide what to do with it so this button needs to be able to spawn in a dialogue scene the dialogue pop-up so let's save our dialogue scene equals preload and now we need the location so it's down here so it's in rest colon slash dialog system slash dialog popup dot tscn and that seems fine i'm also gonna add a variable for the instance which is now by default just so when we spawn one of these in we can keep track and make sure we don't have several open at the same time as i would get pretty confusing during gameplay now before we actually use these let's decide on what our dialogue is so the way i'm gonna do this is our dialog is a dictionary because this way we can have several options and well we can really go quite nested in this and just keep adding more information however we like so what we can do is for starters say dialog option 0 this is a key we can use to access what our initial option is and it has an image so we can say image is and what is it called necromancer.png for example and i'm making up these keys you don't have to use the same keys i'm using here but you have to keep whatever you call these things consistent that way a script can later identify what you're trying to do so we can put some text in here and say npc text and we can put some options in here and these are going to be the selectable options the player can actually click on to decide what to do next now the options are a list because as a list or an array we can just iterate through them easily and pick one but each option itself is again a dictionary so we have text option one and i'm gonna keep it like this for now text option two text option three and in the case of option three we're just gonna exit so i'll put that in here and this is roughly what one of these dialogue things might look like but currently we only have number zero we will also want to have number one and so on you can call these whatever but i'm just gonna number them that way they're easy to tell apart but now how are we going to specify which one to go to next here's a comma so to specify where to go next i'm just gonna say on each option here we say next is one and that would mean that after we click this option this dialog here is going to be left and we instead go to this one then we can say two and in this case because i want to exit i'm going to keep one constant just to make sure we are able to exit things instantly so on this one i'm just going to say -1 this way we have an easy constant predefined which allows us to exit so whenever -1 is in here we don't look for another option we just exit i'm gonna define that in code in a bit but for now we just decide what we want these things to work like and then we implement it afterwards so in case one let's just say we keep to the same layout of course icon.png we use the godot icon here say texts is a reply one say our options are actually yeah we only have one option here we don't want to get too complicated text is exit and next is minus one okay that one's fine go on to option two which still is referenced up here and say image is let's just use the necromancer again text is reply to options is and again just exit or whatever or continue or whatever you want to write i'll stick to exit next is -1 and so everything closes what we can also do instead of quitting here we could just tell it that in case of number one we just go to number two or we could go back to number zero so now if we click here this button it would take us to this dialog where it says replay one then if we click this button it would take us back to the beginning and would just keep letting us loop until eventually we click either the exit option or option 2. i'm not doing that right now just some examples the structure here can look a bit confusing when you're not used to the whole nested dictionary stuff yet but i think it is pretty simple once you get down to it you really just gotta decide on a few keywords you want to use and then put in the values each time essentially you can just copy one of these over to create a new one so now we have an option three which is currently not used anywhere but here it is it's always the same setup so let's get rid of that again and decide how we are implementing these now we could say to always start at number zero but since you might name these based on what they actually do and stuff instead of numbering them like i did i'm instead going to say create a var start and then we can put in whatever our start position is now we want this button to be able to actually spawn in a dialog pop-up since we don't want this to always be visible so i'm gonna delete this we do have it as a separate scene and let's hook up the button to itself and now we can tell it if inst doesn't equal now that is if a dialogue is already open for some reason then we say q free the old one get rid of the old dialogue we don't want to open at the same time if we're trying to open a new one and there's already something open get rid of the old one then create the new one so now we can say inst equals dialog scene dot instance as defined right up here we can say i'm just going to say conversation data equals dialogue and i'm going to say conversation start equals start yeah i already recognized these things because i used them in a previous in the previous version of the script that should be fine let's go in here now we have these two conversation data and conversation start these two variables don't exist right now we're gonna have to create them and of course we're gonna have to say get parent dot add child hints otherwise it's not gonna spawn now if we try to run this it's crashing because it says conversation data doesn't exist and it would also crash on conversation start so let's create these we can go in here we can create a script for this and give it these variables i'm just gonna make some lines here so var conversation data equals empty dictionary by default and var conversation start equals zero by default it doesn't really matter we always gonna override these but just so we can see what data type these should be now i'm gonna create a setup function so this is not a pre-built function this one i'm gonna create myself i'm just putting an underscore there because it's an internal function that shouldn't be used anywhere outside of the script so here is where we actually start setting up our entire dialog view whatever should currently be displayed is going to be done in here so let's just save our data equals conversation data at a specific position now we can just say section in here so we know what section to grab here and this section here refers to what we did in this script so this is section zero section one section two we're gonna be using these here and now to actually set this data we are going to want to know where all of the changeable things are like this image this text and so on let's just create some variables for these real quick on ready for npc image equals vbox container slash npc section and there's the image on ready var and pc text same thing just with the text there it is and on red devar player option box whatever be box container okay you want the vbox container in here this thing okay that should be fine that should be usable we can go in here and say npc text dot text equals data dot text now i'm using the dot operator here to access whatever is in here so i'm saying this thing is what we currently have loaded dot text alternatively you could write data input string text so you could use this this is the same thing we're doing up here the uh 0 is put in a section and opened here that's fine either one works i just use the slightly shorter version dot text and the same for all of the other things here a dictionary is quite similar to an object in our scene tree so we can also treat it quite similarly by using the dot operator npc image dot texture and we can't really predo this because we don't know ahead of time which texture should be loaded here if you want to have them pre-loaded or if you feel like it's necessary i guess we could have an auto load or something and preload a whole bunch of images in there and then just use them here whatever you like in my case these are 64x64 sized images they are really small there's no need to preload this i can load them at runtime and nobody's going to notice so these are at position dialog system slash images they should all be in the same folder for me so i can use it like that and then just add the data dot image name since as we saw here i only specified the name of the image not the full path to it no point doing that if they're all in the same folder just a bit easier to type everything out like this now we have this let us go yeah let's test this actually so to test this we can just use the ready function and on ready call set up of conversation start let's give this a shot there's our necromancer and npc text just as we wrote in here necromancer npc text the options aren't visible yet that's the next part we need to do so let's get to it now since i'm not just using the setup function once at the start but also whenever we click a button what we are going to want to do is make sure that any options that already existed in our list now if we go in here this v works container could already have some children we want to get rid of those first before we spawn in new ones so let's do that for child in player option bots dot get children hold on child dot q free easy and now that these are gone we can create our new ones so for option in data dot options again we name this options this is not a inbuilt thing this is this here this string var button equals link button dot new i'm using link buttons here you can use different type of buttons if you prefer the way they look this is just a stylistic choice button dot underline equals link button dot underline mode on hover because i prefer that i don't want them to constantly be underlined only when i hover them this way there's an easy visual indicator that we are hovering a specific option button.txt equals option.text because that's what we specified so now that we have this we want to actually connect the button to something we need a function to call when the button is pressed so let's just create one func on player option button crest next and this next here is a variable that isn't technically part of a button if i go in here and say add a button then you can see here press doesn't specify any specific data it's not going to pass us anything useful but that's not a problem because we can add this manually so for now let's just say if next is equal to -1 that's our constant we specified earlier in which case we just want to quit the current dialog then just say q3 and get rid of this entire dialog window otherwise call setup again this time using the next value to specify which section to get our data from so originally it starts out with the conversation start which is probably gonna be zero now whatever is has been pressed if it's not minus one this is where we go next now let's connect this button to that function so button.connect pressed self and the function is on player option button a bit long but that's fine at least it's clear what it does and now here is the thing normally this is all you're gonna use when connecting a signal but it's a bit hard to read right now but you can see here there's still a thing for binds so there's an array where we can include additional information so what we can do here is put that array and we only need one value here we only need options.next so this option.next so this value here which is the next value we need here is now going to be stored inside of our connection between the button and this function so whenever this button is clicked we will also get this as an additional parameter in here that's what tells us which of the buttons has been clicked since we don't actually know how many there are so we can't make a separate function for each one so instead we just store which button is this and pass it as an argument here now we of course need to add the button to the box so playeroptionbox.ad child otherwise it's not going to be visible even after we create it now let's take a look if this is working we gotta run this okay so it spawns this stuff up here is fine still we have three options option three should just close the window and it does spawn it again option one should go to a different thing and there we go reply one with the godot face and option two goes to another necromancer thing with reply too so the rest is just customizing this text and doing whatever you want with it really so say i go in here and i just specify what i mentioned earlier i go back to zero then i can say this stuff option one this doesn't exit anymore it just goes back now i can press this as often as i like it keeps going back until i press either exit or option two and then exit the text doesn't really fit here anymore now that i changed it so this should be like a start conversation or something of the sword so the player knows what's going on so yeah these are the basics of what you can do to start out designing a dialogue pop-up of course you can completely change this layout to whatever you like you can make it a bar down here with separate flying buttons i i don't care make it look however you like you can add more images to it you can add all kinds of information to it currently the way i did it there's only a few options in here but say you want a npc name at the top you can just go name colon necromancer and then add a field to the dialogue pop up where this can be displayed and stuff like that so you can customize this however you like these are just some examples i would very much recommend you play around with that some more and see exactly how you can change it and to try and get a feel for this kind of structure even though in reality in large games you would normally save this kind of stuff into a separate file often times a json file because it's very easy for people to edit even without much programming knowledge but a json file has almost the same structure as what you see right here so anything you can do in here you can very easily transform into a json file save it externally and load it up on startup very easy to do this also allows you to do stuff like localization you can say currently the text is just a string but you can instead make the text another dictionary put it like that and say en us or something like that i think that's how the format for these wars and en uk other npc texts you can have custom text for each language then inside of the structure and very easily let people edit it so you can just prepare the structure have this empty or some placeholder in it and then tell somebody else to translate all of the things you want to have changed so that's why you usually save this kind of stuff into a json file instead of putting it in your code it's easier for other people to edit it who don't need to mess around inside of your code but the structure is the same so play around with this first and then get to the other stuff later would be my suggestion if you're new to this kind of thing anyway this will be all for today bye you
Info
Channel: iaknihs
Views: 1,328
Rating: undefined out of 5
Keywords:
Id: QUpJjc6xVwQ
Channel Id: undefined
Length: 27min 50sec (1670 seconds)
Published: Mon May 10 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.