Dynamic NPC Dialogue System Tutorial
Dialogue BP Created By: Gmc
If you have any questions, feel free to message me on the forums!
(This should work for all versions, but the ones listed are the ones I used to make this tutorial!)
Contents
Introduction!
Hello everyone! This is going to be my tutorial on how to make a Conversation BP so that all you have to do is type in the text that the NPC will say and what the Player will be able to say back! There are a few text modifiers that you will need to add to your text for it to work correctly (IE. /br for a new line, and /lv for if the line will end the conversation. Both of these go at the end of the sentences.)
Downloads:
Images
Here is a link to the .ZIP folder of all of the pictures that will be used if you want to download them and follow along!
(These may be out of date, use with caution)
Conversation Node
Here is a link to the .ZIP folder for the completed Conversation Node
Videos:
Here is the first video to the Tutorial Videos, this one is just a preview of what the BP can do so far!
These videos will most likely be more update than the wiki as of 3/15/2015.
<youtube>
https://www.youtube.com/watch?v=99Tfv7rjk1k&list=PLXeTUtPB4J7IGd7QJA10eglxFLlCeOacy
Here is also the link to the video playlist:
Link
Quick note:
Blue Comments mean this part of the BP can be Changed/Altered/Removed to your liking or need.
Red Comments mean this is Still In Development and is not needed for the project!
Green Comments mean this part of the BP has to be EXACT for it to work!
The Text Modifiers should go in this order from the end of the Text Line: /br,/lv,/mr,/qg. (EX: Hello!/qg/mr/lv/brHow are you?)
NPC Section:
Picture 1/20!
So, to start us off, open up the Trigger image in the NPC folder! The NPC folder is where all of the images for the NPC BP are. This may look overwhelming at first, but I will go through everything step by step. To start us off, if you have not made an NPC Character BP yet, you will need to do that now. It will need to include a trigger component! Once you have done that we can get started! Now that you have your trigger component, select it and click “add event for trigger” in the details panel, we will need the OnComponentBeginOverlap event to start us off! Once you have that, create a branch off of the arrow, and drag off of the OtherActor pin and type in ==, connect the red output pin to the branch. Now right click in some open space and type in: PlayerCharacter, click the GetPlayerCharacter and attach the blue pen to the bottom blue pin of the ==. That is the first bit of our BP well done! The reason we have the == is to make sure only the player can activate the conversation! Now drag off of the True pin in the branch and get a DoOnce function. Now we come to an interchangeable point, depending on what you're going to do with your conversation BP this will be different! If your BP is going to be on the HUD like mine you will need to reference your player character! (The HUD BP is going to need to be a Widget BP, do not use a regular Hud BP!) (If you have not created the HUD, do so now).
(If you have just created it and don’t know how to make it appear on your screen when you play, I will give you a quick explanation! For me, I have all of my characters stem off of one Master BP (I am using Mixamo’s Character Pack) so I will only have to do this once, but if you have multiple player characters that are not referenced by each other this will be harder to do. Ok, once you have opened up your player character put down an event begin, then attach it to a create widget, the HUD Widget BP will go in here! Attach an AddToViewport to the Create Widget (make sure to connect the 2 blue pins together!). Then right click on the blue pin on the CreateWidget and select PromoteToVariable, you can name it whatever you want! That's all you need to do in the BP for now!) Now go back to the NPC and drag off of the PlayerCharacter and type in CastTo(name of the player BP) and connect the input arrow to the output of the do once! (If your Conversation BP is going to be in a bubble or something above the NPC or whatever else, you will need to cast to that instead, this way is a little different.)
Now drag off of the cast node from the blue pin and get your HUD variable (or whatever you called it). Now you will need to make a DataStructure BP, Create-Blueprints-Structure, open it and add 2-4 varies depending on if you want pictures next the character and NPC text, the variables are: 2 Texture 2D and 2 Text variables, name them whatever! Now go to your HUD BP and create a new variable, it will be a bool at first, just click on the variable type and change it to whatever you DataStruct was called (its name) Make sure to make it public! Now go back to the NPC, drag off of the HUD variable and type in the name of the variable you just created! Make sure you SET it not GET it. Then connect the input pin to the output of the cast node! Now, instead of what I did, (I used a Make Struct function) you can just right click on the dark blue pin and click SplitStructPin! Next, you will need to make variables of all of the new pins you have (you can just right click and promote them, but when you promote the Pink ones, delete them and make each one into an array) now CTRL drag them onto the graph and drag off of them and get a Get node, attach them to their respective input nodes on the SetStruct node. Now head back to your Hud and make a variable of the NPC (this will be its name, make it public!) Also while you there quickly make a CustomEvent. Now go back to the NPC and drag off of the hud and Set you new variable to SELF, then drag off of the hud again and type Call(name of your new CustomEvent) Now you are done with the First Picture! We are well on our way to finishing this BP! Only 19 more pictures to go!
Picture 2/20!
You will need to open ConstructionScript in the NPC folder! These next 3 Pictures are going to be pretty quick, so I’m going to compile them all into one! As the pictures state you will need to open up the Construction Scrip of your NPC! Right click on the graph and get the SELF node! Drag off of that and get the Set Material Node. Promote the Material pin to a variable and make it public, this way whenever you duplicate you NPC, if it looks different all you have to do is change the public MAT variable! This next blue part is to load from a save file what character you're playing as so it can correctly set the Character Image when you're talking to someone! For now we can just make it, but not connect it since it won't work unless you have a save game and pictures of every character, when you do all you will need to do is connect the white arrows together! ALT drag off your character Image variable (if you don't need images in your conversation, skip this part) Now make a new DataStruct with however many characters you have (including different genders) (the variables will need to be Texture 2D) Now the way I have it set up is with an array of INTs, the first (Array 0) is the character type (swordsman, archer, mage) the second (Array 1) is the gender, after that is what the character has equipped (one for Head Armor, Leg Armor, Weapons, ETC.) This how I did it, you can do it anyway you want! Now make a new variable for the new Data Struc you made, CTRL drag it onto the graph, and right click the pin, and choose Split Struct (I did not do that but its cleaner this way!) Now depending on how many different character types you have, you will need to make a Select Node with that many options, if you have Genders also, make a Select for that too (you will need to duplicate the first select for however many genders you have) Now attach the output pins of the Data Struct Variable to the corresponding Switch Nodes (the gender switch node goes last) and attach the output of the gender switch (if you have one, if not then the first switch you created) to the character image variable! We are now done with the Construction Script!
Picture 3/20!
LeaveAndSendLines in the NPC folder! This is the rest of the graph for the NPC! We shall start on the left side and go down! First, make a custom event that will be called from the hud when the player wants to leave the conversation! This next part is if your NPC is an AI and walks around (Mine does, so when it receives this is will walk away from the player!) Later on I will add a function to this that will let you choose if you NPC walks around, or is maybe a merchant or something that stays in one spot! But for now you will have to choose, Either Or. Once you have decided on this, create a new INT variable and ALT drag it onto the graph, connect it to Either the Event OR the SetValueAsBool Function if your AI walks around! Now on to the bottom of the Picture! Depending on how many Options your character can choose! I could make this so you only have to make 1 event and it checks to see what options was clicked and act accordingly using an INT variable, but for now we shall leave it like this! Next Make a new Custom Function by going into the top right part of the screen and clicking on the big F! Attach this new function to each Event by dragging it from the variables section onto the graph! We are now done with this picture!
Picture 4/20!
SendLinesFunction Still in the NPC folder! Before you start, if you want to make a custom variable out of the Hud variable that comes out of your cast function from the first picture, do it now (This will make things easier in the Custom Function) Open up your newly created Custom Function! If you made a new variable for the hud variable, you do not need the blue comment part, just get your new hud variable, drag from the pin and SET the Conversation Data Struct (the one with the pictures and text) Split the Dark Blue pin, and connect the input to the output of the purple box! Now get each corresponding variable and connect the to the split pins, Also I did not mention this, but the Text Arrays need to be Public as well as the NPC Image. Now click on the purple box and under Inputs click new and change the variable into an INT, now CTRL drag the first INT variable you made, connect it’s pin to a Multiply node (just put in ‘INT *’ and you will find it, make sure its INT * INT) and set the button number to however many options you have, as I said before this will be dynamic later on! Now drag off of the * node’s output pin and get a + node, connect the bottom of this to the purple box’s INT pin! Connect the + to the Get Array Node’s INT input pins! Now ALT drag the INT variable you made, connect its Input Execute pin to the Set Data node’s output pin, drag off of the Set Int Node and attach it to the Multiply '+' combo from the Int variable. Now drag off of your HUD variable and call the custom event again! Now you're done! Until next time!
--GMC
Dialogue Widget Section:
Pictures 5/20-9/20
There are 5 pictures in this section! CharacterTalkWidget, CharterExitWidget, and SizeBoxWidget, CharacterWidget, and CharacterWidgetGraph! They are located in the Hud&Examples folder! We are finally onto the bones of our system! This is where the magic happens, and becomes complicated! Open up your Hud BP and click on the Designer tab, this is where you will create the layout and looks of your conversations! Now there's a lot in these pictures, and you don't need most of it, since a lot of the stuff in the picture is for my HUD overlay and not used in conversations. Let's get started by adding in 2 Grid Panels. These will hold everything for your character and NPC.
CharacterTalkWidget
Looking at the CharacterTalkWidget picture, we need to set both of these grid panels like so: Anchor one to the bottom middle of the screen, this is your character holder, and one to the top, your NPC holder. Look down a little and set the Alignment to: X 0.5 and Y can be 0, I made it 2 because the XP bar gets in the way if I don't. Now below that, click SizeToContent, this will let us not have to mess with resizing the grid panels. Now click the plus twice in Column Fill. Set the first one to .5, the second to 1 (if you don't not have pictures you don't need this part) Now go down to visibility and set it to Hidden, then click Bind and Create Binding. This will bring up the BP graph, drag off of the green pin and get a Select node, set the WildCard to bool, and promote it to a new variable. Now set False to Hidden and True to Self Hit Test Invisible. Now go back to the Designer and add 1 SizeBox to the grid panels. Then add a VerticalBox to the SizeBox, this is where all of the text will show up! Next under the Size box, in Column, set it to 1. Also, if your conversation will have images, add a scale box and add an image to that. Set the image Alignment to center. Also set the VerticalBox Alignment to full. (Everything should be set to full except for the image)
SizeBoxWidget
Now open up the SizeBoxWidget picture, this will determine the max/min size of the conversation boxes, you can make this whatever size you want, but be careful of overlap and it goes off screen or being too small! To set up the max/min size, make sure the Horizontal and Vertical alignment are set to full (the big bars going left/right and up/down.) Next, go to child layout, the last 4 options are what you want, these will set the max/min size your conversation box can get!
ChacterWidget
Now open up the ChacterWidget picture, this is a separate widget BP you will need to make, you will need to make 2, one with a button for the player and one without for the NPC. Once you have created the new widget BPs add a button to the Character Widget (This will be the root, so make sure to delete the Canvas Panel before adding anything! This goes for the NPC Widget too!) Next, add a Scale Box to both of the Widgets, and a Text Block to that!
CharacterWidgetGraph
Now open the CharacterWidgetGraph picture. Go to the graphs of both Widgets and a Text Variable and a bool to the Character Widget, this will tell us if the button is clicked or not! Now go back to the Designer and for both Text Boxes, under Content, Bind the Text to the newly created Text Variable! Also for Button in the Character Widget, go down to the bottom where it says Events, click OnClicked, this will bring you to the Graph section. ALT drag the Bool and connect it to your OnClicked event! Make sure all of the variables you made are public! Then create a new Event Dispatcher and connect it to the Bool. Now go back to your Conversation BP (or HUD BP) and in the top left of the Designer, scroll down to the bottom. There you will see your new Widgets you just made! Go ahead and drag the Character Widget into the VerticalBox for the Character Holder, this will be our Leave Conversation option, which is why we are adding it now, this will make it not able to be deleted like the rest of the options, although if you do not want the player to leave mid conversation I might add an option later to make it invisible!
CharacterExitWidget
Now open up the CharacterExitWidget picture! This shows how it will be setup! You will need to make the Size option, under Slot at the top, Full and the Alignment to Full also! Then in the Default box, put something in Conversation Text indicating that this is the leave option! Right below that, in the style section, you may need to change the Foreground Color to Inherit so the text will be Black (you can also just make it black and it does not have to be black either, its just easy to read on the white button, which you can also change the color of! This is the Color and Opacity option right above the Foreground Color!) And now we are done with this section! Hoorah! --GMC
Dialogue Graph Section:
Picture 10/20
‘Create’ in the Player folder! We are now onto the BP section of our Conversation System! You remember that Custom Event you made here once? That is going to be the start of it all! Once you have opened the Create picture, get the InputModeGameAndUI Function, the Target will be the Player Controller the Widget to Focus can be Self (I have something different, but id does not change anything). This will let our mouse be seen, if you do not want the mouse to go offscreen, click Lock Mouse, also make sure Hide Cursor is NOT clicked! This next part is for pictures only, if you don't have pictures, skip this! (If I have said this already then sorry: I am planing to make the pictures also an option for if you want them or not! For those people out there with Bubble Conversations, it may not look good with the pictures! I could also make it so you only have one picture!) To start us off, CTRL drag the NPC Image and Character Image onto the graph, drag off a Set Brush Function from their pins. Now CTRL drag the Conversation Data Struct and split the pins! Attach the blue pins to their corresponding inputs in the Texture pin of the Branch Function! Now attach a Sequence Node to the Brush Output. Create a new Custom Function, this will split the text lines if there is the /br modifier or exceeds at character limit (Work In Progress). Create a String Variable for it’s Input, the Output will have one Bool and 2 Text Variables (Ignore everything else). Now drag off a Branch Node from the Custom Function you made. Off of the true, make a CreateWidget node, then right click on it and press Collapse to Nodes. Remember to do this twice! Now in these newly created Nodes, make 2 Text variable pins and 2 Execute pins in the Input, the Output only needs 1 Execute. Create 2 new String Variables, one for the NPC and one for the Character. ALT drag these and hook them up to the Output of the Nodes you created, then right click the Set String Variables and make them into Nodes! These nodes need no output, just 1 String input. Drag the Text pin from the Data Struct to the Input String pin, it will do the conversion for you!
Picture 11/20
CheckLineFunction in the Player folder! This is the picture for the Custom Function you made in the before section! Open it up and lets get started! First off, the Red Comment can be explained . Drag off of the String Output pin, and get the Split Function, set the In Str to: /br (Or whatever modifier you want to put in the text to mean its a new line! I recommend this only being 3 characters, or you might have to modify the Right Chop coming up) Drag the Left S to the Left Text Input pin in the purple box to the right, it will convert it for you. Now for the Right S, drag off and get Right Chop to take off the modifier from the text (So it wont show up in the Conversation). Take it’s Output and connect it to the other Text Input pin. Lastly, hook up the Split’s bool the Input bool on the right!
Pictures 12/20-13/20
1NPC
1NPC in the Player folder! Ok to start us off, open the first Node you created with the CreateWidget, make sure its the NPC node, the Character Node will be a little different. Connect the Create Widget to the Left Purple box, assign the class to your Custom NPC Widget you made earlier. Now CTRL drag the Vertical Box for the NPC onto the graph, drag off of that and get Add Child, connect the Content pin to the Blue Output pin of the Create Widget, and hook up the Executes. Now drag off of the Blue Create Widget pin and get the Set Slot as Vertical Box Function, drag off of that and get Set Size Function, split the pin and make sure it’s set to Full. Now right click the Blue Widget pin and promote it to a variable, go for how to make this dynamic. Make sure to hook up the Execute pins for the Set Variable you just Promoted. One last time, drag off of the Blue Widget pin and set the Conversation Text Variable, hook its Text Input pin to the first Text pin in the Blue box on the left and hook its Output Execute pin to the right Blue Box. Now for the bottom part of the picture...just select everything you made above and press CTRL W, make sure to hook up the execute pin to the Left Blue Box (not the right) and the Set Conversation Text pin to the other Text Pin in the Blue Box.
1Character
Now open up the 1Character Picture! This is a little different, but go ahead and CTRL C everything you did just now, CTRL V to paste it into the Character node (you might have 2 sequence nodes now, just delete the one that is not hooked up to the Create Widgets. Now here comes the part that is different. Create a new Custom Function in between the Set Character (Replace all the NPC stuff with the Character stuff, this includes the Class for the Create Widgets) This function will need a Text Variable Input and Output, also an INT Input (set this to 1) Drag off of the Text Output pin and get Format Text, in the format section type this: {Number} {Text} (you can just copy paste this into it) now there will be 2 more Text Input pins, in the Number pin put ‘1)’ (or what numbering system you want) and connect the Text pin to the Text Output pin of the Custom Function, connect the Text Output pin of the Format Text to the Set Conversation Text. Now you remember that Binding you made in the Designer with the bool variable? ALT drag that and set it to True (check mark). Do everything the same for the bottom part of the picture! (There is possibly a bug with the Format texts, whenever I change the Format options, I get an Internal Compiler Error. If you get this, just save everything and close unreal, when you reopen it, it will have fixed itself).
Pictures 14/20-17/20
NPCLoopLeft
Ok, so once you have opened up the NPLoopLeft picture, open the 2nd Node you you made with the Set String Variable. Attach a While Loop to the execute of the Variable, Promote the bool that comes with this and set it to True by default. Now if you copied everything for the 1Character part, just paste that here, but delete the bottom stuff, also the Source String for the Check Line Function you will attach to the variable at the beginning of this node. (Just CTRL drag it onto the pin) Now this next part of the picture you can ignore because it is not finished yet!
NPCLoopRight
You may want to look at
and
while working on this picture!
Ok, open up NPCLoopRight! Attach a Branch on to the Check Line Function, connect the Bool from the Function to the Bool of the Branch! Now for the True Execute pin Set the String Variable that we were using to the last Text Output pin of the Check Line Function. Next, you actually don't need the Set Bool, just skip it and instead Set the Conversation Text for the Create Widget. Now get a Switch On INT, you don't need the default pin and make sure there are 1 less than the max amount of options you character can have, right now you will never get the last option, but it's good to have since you will need it later. (This will change when I enable the ‘Story’ Function). Promote the Switch’s INT Input. ALT drag the 3 duplicates of the Create Widget Variable and connect them according to the picture and connect their Outputs to a Set INT Variable. The Input pin of this will be attached to an INT+INT adding 1 and connected to the Get of this Variable. Now CTRL W all of it and attach it to the False Output of the Branch, make sure to add a Set Bool for the Loop Bool and set it to False (no check). Also the Conversation Text will be attached to the String Variable you have in this Node. Lastly, delete the + connected to the Set INT and set it to 1.
CharacterLoopLeft
Now open up the CharacterLoopLeft picture. This is mostly the same as before so you can just Copy Paste everything into the Character Node, just remember to switch out all of the NPC stuff with the Character equivalents! Ok we don't the LoopLeft picture anymore, but we do need the CharacterLoopRight!
CharacterLoopRight
There are a few differences here than the NPC one. In Between the Set String and Set Conversation Text in the top, we will need the Custom Function we made in the 1NPC and 1Character sections! You also remember that Format Text we made? Copy and Paste that too and connect it to the Custom Function! Although there is one thing you need to add to the Format, if your numbering system has something after the number (IE. ‘)’ ‘.’ etc.) put it after {Number} in the Format section, so it will look this this: {Number}). Now attach that to the Set Conversation. Ok, for this next part, the picture does not have an + node, you will need this for the Set Variable and the To Text (INT), but just connect the regular variable to the INT Input of your Custom Function (No + node). Now do everything the same for the bottom part, just remember to set the Set INT Variable to 1 and add in the Set Loop Bool and set it to False!
Picture 18/20
CheckLV in the Player Folder! So first things first... this picture is also wrong! You will need to add a Subtract INT onto the INT Output, set it to subtract 1! You will also need to manually convert the Text Variable to a String! Just drag off of it and type in: String! Now off of the String converter, get an Ends With Function and set the Suffix to whatever modifier you want and the end of a Text Line to indicate that it will end the Conversation (this can be as big or small as you like, compared to the first modifier we made! However, be careful with some ones, especially real letters, it will take out EVERYTHING with the modifier. So if you put ‘the’ as the modifier, you will no longer have ‘the’ in any of your sentences and most of your sentences will end the conversation (since most Conversations have ‘the’ in the line!) Next, you will need to create a new Array of Bools, it will have as many Bools as there are options for the Character to choose from! (This could also possibly be dynamic by changing the Set Array Elem to Add Array Elem or setting Size To Fit to True on the Set Array Elem, but that might not work right now.) So once you have created the Bool Array, CTRL drag it onto the graph and drag off of its Output and type in Set Array, hook the Index to the INT Output in the Purple Box and hook the Item to the Bool Output of the Ends With Function. Now drag off of the String Converter again and get the Replace Function, set the From to you Leave Modifier and the To leave as blank. Drag the String Output of the Replace Function onto the Input Text Variable in the Purple Box to the right, it will convert it for you! We have now finished with the creation of our Conversation System, now we need to reset it back to its default state!
Picture 19/20
This has been drastically updated
!
Destroy! Since taking this picture, I have greatly updated this part of the section to get ready for a Dynamic number of options, so I will have to walk you through this with little help of the current Image you have (some stuff is still the same though!) We shall first create the Event Tick with a Sequence attached to it. There is a branch attached to the first Then and a second Sequence to the second Then, add as many execute pins are there are options for the second Sequence. Also add a DoOnce to the first Branch. From here we will do as the picture says, but anything with a Reroute Node do not attach or the other 2 Sequence Nodes! I will get to that later! Let's start with the top first. Off of the DoOnce get the Set Input Mode Game Only Function, this will make the mouse go away, make sure to attach the Target to the Player Controller! Next ALT drag the Bool that turns the Conversation on and set it to False. Now CTRL drag the NPC Cast Variable and Cast to the NPC. From the Cast’s Blue pin, Call the Custom Leave Event you made. Now CTRL drag the Widget that you created for the Player to press to leave the Conversation, duplicate it, put one by the Event Tick and one in front of the Leave Function. Off of the Event Tick one drag and get the Clicked Bool, attach that to the branch Bool Input. Off of the one by the Call Leave Event drag and Set Clicked Bool to False. Now make a CTRL drag all of the NPC and Character Widget References onto the graph and turn them into a Custom Function. Now do not add the Sequence Node as the picture says, instead select everything from the Set Input to the Custom Function you just made and turn all of that into a Custom Function! Then attach the Output of the new Custom function to the Reset of the DoOnce!
Now onto the bottom part of the picture! Go ahead and CTRL drag the 4 Character Widget References and the Array Bool onto the graph! Next, drag off of one of the References and get the Clicked Bool (you only need to do this once), off of the Array Bool get the Get Function and duplicate it as many times as there are options for the player! To set the INTs, start from 0 and add 1 to each next one (The last number should be the Max - 1). Now attach one branch to the first Then of the second Sequence Node, off of that, a DoOnce, and a second branch. Attach the first Branch’s Bool to the Get Clicked Bool, the second to the Get from the Bool Array. Do not attach anything to the Reset of the DoOnce just yet. CTRL drag and get the NPC Cast Variable again and cast to the NPC, attach the to the FALSE pin of the second Branch. Off of that attach the Custom Function you made with all of the Widget References. Then drag off of the Blue pin and get all of the other Custom Events you made in the NPC BP. Select all of the stuff you just made from the Get Clicked Bool to the Custom Function and make all of that in a Custom Function! The only things left should be the Character Widget References, get Array Bool and Get Array Bools and the Custom Events! Now we are done with this picture!
Picture 20/20
RefreshWidget! This is the last part of the Tutorial folks! Now lets get started shall we! Before you open the picture, let's finish the last custom Function you made! Open it up and in between the Custom Function and the Purple Box, add a Sequence Node! Then 1 will be hooked up to the Reset for the DoOnce. Off of the True of the second Branch attach the Custom function of everything you made in the top of the Destroy picture, also connects its Output pin to the Sequence. We are now done with the Custom Function so open up the Custom Function before the Sequence Node connected to the Cast Node, also open the RefreshWidget picture!
Drag off of one of the Widget References and get the Remove From Parent Function, attach all of the References to this and attach it to the left Purple Box! Now ALT drag both String Variables and Loop Bools you made onto the graph! Connect them to each other and the beginning one to the Remove From Parent. Set the Strings to blank and the Bools to True. Now get the Set Clicked Bool variable from one of the Character References, duplicate it and attach them to the rest of the References! Now ALT drag the Bool Array, drag off of its Input pin and get the Make Array Node, add as many pins as there are Options! Connect the Set Array Bool to the right Purple Box. Now you're done! I hope everything works (I diverged away from the pictures a bit, so some things might not have been explained well) You can use the 2 unused pictures in Hud&Examples as an example for what it should look like (roughly) and how you would set up the Text Lines for the NPC and Character! In the ExampleNPCSetup, the 4th Text Line for the Character (number 0, 3rd /br) has /lv at the end of it, which is why, for the NPC, the 5th (number 4) line is blank, since there is no continuation of the conversation for that option! NPC(0) -> Character(0) -> NPC(1-4) -> Character(1-4) respectively, Character(1) -> NPC(5-8), Character(2) -> NPC(9-12), etc. (That is probably very confusing, you may just want to experiment with it!) --GMC
Advanced Sections
This is where a sections goes if it does not have a picture(s) yet, so they may be harder to understand!
Dynamic Widget References
I have found out how to add the widgets you create to an array instead of their own reference variable! I was doing it correctly up until I tried to remove them from the array! (if you attach a Remove At Index to a For Loop to try to remove them from the array, the ForLoop will not loop correctly, instead you must use the Clear Function to clear the array!
So here is what you can change (you don't have to, it still works without doing this!), turn one of your Reference Variable (for the NPC and Character) into an array, then you will use an Add To Array Node to add the Created Widgets to the Array in the 1NPC, 1Character, NPCLoop, and CharacterLoop Nodes! Then in the Destroy Node, instead of 4 Custom Functions connected to each Widget Reference, you only need 1! This is what you have to do: off of the first Sequence Node, create a DoOnce, then a ForEachLoop with the Character Reference Array attached the attach the Custom Function to that with all of the correct pins! Connect the Completed Output to the Reset of the DoOnce. Inside the Custom Function it should now look like this: Branch with the Clicked Variable attached, the a second Branch (delete whatever is in between) with the Bool Array and a Get Array attached, the INT of the Get is attached to the Purple Box INT. Then the 2 Custom Functions attached to the Branch, open the one attached to False. It should look like this: ForEachLoop with the Character Reference Array attached and a Remove From Parent attached to that, attached to the Completed is a Clear Array Node attached to the Character Array, duplicate that and replace the Character Array with the NPC Array, this will be attached to the first Clear, then attached to that would be the 2 Set Strings and Set Loop Bools and Set Bool Array, delete everything else! Now one last thing. Go to the NPC and delete the Custom Events at the bottom, you will only need one, this will also need an INT Input. Connect that to the Custom Function you have in the NPC including the INT pin. Now go back to the Conversation BP and the Custom Function you were just working on, Call the new Custom Event you made in the NPC and attache the INT Input to a + and attach that to the Purple Box INT, also set the + to add 1. Now you're done and it should dynamically add as many Widgets as you need! --GMC
Dynamic Line Splits
I have finished the function to split your lines in half if they get over a character limit, that you can set! I am still working on the story mode, so be careful of too many Text Boxes!
The first 2 things you need to add are in the NPC BP: 2 public INT variables for the Max#ofTextBoxes and Max#ofCharactersPerLine. Now, in the Conversation BP, in the CheckLine Function, the picture for this is almost correct (the Red Comments), however, these things need to be changed: you will not need the bottom part of the Top Red Comment or the bottom part of the Bottom Red Comment! Also, in the Top Red Comment, change the >= to just >, and hook the unhooked pin up to the Max#ofCharactersPerLine from the NPC. Now create a Branch an connect its left Execute pin to the left Purple Box and its Bool pin to the >. Now make a new Custom Function and put it inside this function, this will make sure your words do not get cut in half when it splits the lines!
Attach the New Function to the True of the Branch, the False will be connected to the right Purple Box, same with the Out Execute pin of the added Function, you will need to add a String Input and 2 Text Output pins. The inside of the Function will look like this: off of the String pin get a LEN then divide by 2, get 2 MID functions and attach the Scource to the String pin, the first MID's Count will be attached to the Div 2, both of the pins for the second MID will be attached to that. Off of the MIDs the first will have the function Ends With, the second Starts With (both of the In pins (In Suffix/Prefix) will have a space), off of those a Select. The Bool of the Select will be attached to the Ends/Starts with, the False a Local String Variable (you will need 2, one for each Select), the True will be attached to the MID, the ends of the selects will be attached to the right Purple Box's Text pins. Off of the left Purple Box's Execute, set 2 new Local INT variables to 1, then a Branch, True connected to the right Purple Box, False to a Set Local Bool True, connected to a WhileLoop, Body connected to a Branch, True connected to Set Local Bool false and Set first Local String, False connected to Set first Local INT, its pin connected to a +1 connected to the first Local INT. The WhileLoop Bool is connected to the Local Bool, the Branch's Bool to a new Ends With, same Suffix as before, the Source it connected to a MID, its source connected to the Purple Box's String Pin, the Count connected to a -, first pin connected to a div 2 connected to a Len connected to the Purple Box's String, the other pin of the - is connected to the first Local INT. Off of the Completed pin is everything duplicated starting at the first Branch's False, but some things are changed, first Local INT replace with second, replace Ends With to Starts With, replace Set first Local String to second, also the MID's COunt is connected to the div 2, the start to a + connected to the div 2 and second Local INT. Off of the new WhileLoop's Completed is a Branch, True connected to Set second Local String connected to the right Purple Box, False to a new Branch. First Branch Bool connected to first Local INT and second Local INT connected to a < connected to the Branch, the Set second Local String is connected to a MID, Source String to the Purple Box, the Start to - connected to first Local INT and div 2 connected to Len connected to Purple Box, Count connected to + connected to first Local INT and div 2. Off of the second Branch, True connected to the Set second Local String, False to Set first Local String connected to the right Purple Box. The seocnd Branch's Bool is connected to an == connected to the 2 Local INTs, the Set first String is connected to a MID (You know where the rest of the String Inputs go), the COunt is connected to a + connected to second Local INT and div 2 connected to Len. Done!
Now in the Create picture, you will need to add 2 more Branches to the NPC section after the CheckLine Function, hook them up to the True and False of the first Branch so that the first Branch is connected to False and the second to True, reconnect the first Branch's Condition pin to the other Bool pin on the CheckLine Function and the other 2 Branches will be connected to the first Bool. Next, you will need to add 4 things to the Input of the 1NPC Node: 2 Execute pins and 2 Text Pins, the first Execute will be connected to the True of the second Branch, the second Execute to the False, this is the same for the first Branch and its corresponding Execute pins. In the Output you will need to add 1 more Execute pin. In the NPCLoop Node you will need to add an Execute pin and a Text pin, connect the other Execute pin on the 1NPC node to this new Execute pin, the Text pin will be connected to the last text pin of the CheckLine Function (Make sure you have removed the extra pins on that!)
Ok, now open up the 1NPC node, off of the first new Execute pin, duplicate any of the setups you previously made 3 times, connect 2 of them and that to the Execute, at the end of this add an ALT Loop Count Variable set to 2 and connect that to the right Blue Box's first Execute pin. The Set Conversation pin's will be connected like this: first to the first new Text pin and the second to the second. For the other duplicate, connect it to the second Execute pins of both Blue Boxes. The Set Conversation will be hooked up to the first new Text pin.
Now in the NPCLoop Node off of the new Exectucte pin, duplicate the Set NPC Text and attach it to the execute, its pin will be attached to the new Text pin and the Output to the While Loop. Now set up the branches in this node like the ones in the Create section, but add one more before it with this hook up to the pin: >, top pin is Loop Count, bottom pin is the Max#ofTextBoxes from the NPC. The current stuff you have will be hooked up to the second Branch. The first Branch will look like this: off of the True, duplicate everything off of the first Branch's True (the one with the set loop count +1), set the Set NPC Text pin to Right, Set Conversation Text pin to GLeft, Add to the NPCArray to the Create Widget, and Set Loop Count connected to a +1 connected to Get Loop Count, now add a Branch like the one you added above with the >, off of its False (nothing gets connected to the True) just duplicate everything from the Create Widget to set size, and duplicate the left part of this you just made, without the Set NPC Text. Now on the False of the branch, duplicate everything you just made, but replace the Set NPCText with a Set Loop Bool to false and the last Set Loop count to 1 (not +1). --Gmc
Story Mode
You will want to make a button in the NPC Widget Holder in a scale box that is Aligned Full and Middle, the button will be Aligned Full Full, the Visibility set to Collapsed for both and create one Binding for both, in the binding connect a select function to the Visibility, the Wild Card will be a Bool (False Collapsed True Visible), Promote it. Also get the event OnClicked for the Button, put it in the NPCLoop Node. Off of it is: Set NPCLoop Bool True, Set Loop Count 0, the Bool for the new button to False, ForEachLoop with the NPCArrayReferances, off of the body is RemoveFromParent connected to the Blue pin, off of the Complete is a Clear connected to the Array, then connected to the WhileLoop. Off of the WhileLoop put the Set Loop INT +1 here, remove it from the first branch true and the second branch's True, but the second one in the line (the one after the Branch in the line). Off of the first Branch connected to the CheckLine Function, the True will have Set Button Bool to True and Set NPC Loop to False, same with the 3rd Branch off of the 2nd Branch's True, the Trues for the Branches in these sections will be the same. One last thing, you will need to a new Loop Counter for the Character, replace all of the NPCLoop Counts with it in the Character Nodes. --GMC
Merchant NPC
Note: you can add in regular text options along with the shop options, but put the text options after the shop options or it will mess up!
So, to start us off, there's not much you need to add, but lets start by opening the NPC! We only need 2 things: an Actor Array and a Text Array (This one you won't use till the next Tutorial!) these will both be Public. The actor arrays are where your Merchant Items will go, to add them to the array, you can't just "add" them, unless you make a ton of custom items (I use one master Items and change it in game) if you do it like I do, all you have to do is follow Unreal's Inventory Tutorial
! You will also need to add these Arrays to the Conversation Data Array.
Now in the Conversation BP, in the Check LV Function, you will want to duplicate the inside 2 times and attach all of them together, the Bool Arrays are different though. For the first one, the modifier will be /mr, you will put this in the Character Text line to indicate you are selling the Item with that designated slot number (option 1, Array item 1), the second shall have /qg for a quest giver, we will use this later as well. Now in the Reset Function, add 2 more branches and set them up like the /lv branch (false connects to the next branch/function) on the True of the /mr branch, it will need to look like this: cast to your Master Item BP by getting the Conversation Data Array and Get from the Merchant Items and connect the INT to the Purple Box and the output to the Cast, then cast to where ever your Inventory is and Add to the Inventory Array and remember to remove the widget from parent and connect the Refresh Inventory Function you made in the Inventory Tutorial! There is one last thing you need to do, connect the Function connected to the True of the /lv to another /mr branch and connect it to the first cast.
Next we will add pictures and a System so you can't Infinitely buy an Item (The Merchant will run out)! We will start with the pictures, open up the Character Text Widget, right click the Scale Box and click Wrap With, I used a Horizontal Box, but you can use whatever you want! Now put a new Scale Box in the added Wrap Box, then add an Image to that. If you used a Horizontal Box, I set both of the Scales to Full, but the Image Scale too .5. Next Bind both the Scale and the Image to one binding, this will have a Select with False as Collapsed and True as Visible, the Index will be a Public Bool. (Remember to set the Visibility of both to Collapsed by Default.) Also bind the Brush of the Image to a Bining with the Dark Blue Pin set to a Public Variable. Now go to the Conversation BP in the 1Character Node, take out the Enable Conversation Bool and put it in the CharacterLoop Node in the False Branch Section at the end. Now in the /LV Function, add a Bool Output Pin to it, and inside attach it to the Ends With Output Bool. After all these Functions (1Character and CharacterLoop) add in 2 Branches (Or only 1 if you always want pictures, the second branch will toggle this.) the second will be Attached to True (The Falses will be attached to the Set Text), the first Bool will be connected to the Function Output, the second Bool to a Public Bool in the NPC that you will need to add along with an INT Array. Off of the 2nd Branch's True add a Set image Bool off of the Widget, set it to True, then off of that add a New Custom Function. In the Function add 2 Input Pins, a Character Text and an INT (The INT will be set to 0 for the 1Characters, for the CharacterLoop connect it to the LoopCount INT), inside get the Conversation Data and drag a Get off of the Item Array, attach the INT to the Purple Box, off of that get a Cast to your Master Item, from that Get the Item Info and Make a Slate Brush off of the Item Image, off of the Character Purple Box Pin get a Set Item Image and connect it's pin to the Make Slate Brush. Now a Picture of the Item will show up in the corresponding box! (If the Item Image Bool is set to True in the NPC) Now in the Destroy Node in the Reset Function, add a new Branch on the True's of the MR Branches, connect it's Bool to a !=, the First pin will be connected to the INT Array you added to the NPC, the other pin is set to 0. Now off of the False of this Branch you can add a Set Conversation Text and set the text to Out Of Stock, so that if you click on the button and the Merchant no longer has any more of that Item, it will say Out Of Stock and won't let you buy it! (The INT Array slots correspond to the Item Array slots)
I am working on a Buy/Sell System with multiple pages, however, this may take a while since I am trying to optimize it for a shop with a lot of items (You don't want 10 pages with 4 items each), so I am having to experiment a little which takes longer for me to develop a publishable creation!
--GMC
Updated Destroy Section
This video will help you in the mean time!
https://www.youtube.com/watch?v=7ox8DakE7No&feature=youtu.be&t=3m30s
--GMC