Hello and welcome to lesson 5, the final lesson, of the articy:draft Importer for Unreal tutorial series.
Recap lesson 4
In the previous lesson we adapted the project’s dialogue system to handle branching dialogue. For player choice points articy’s menu text is displayed to give the player an idea in which direction the reply goes without already giving the entire dialogue line away.
In this lesson we will take a look at what needs to be done to display more complex dialogues and make an improvement to the NPC interaction.
Both our test dialogues run flawlessly, but how does it look like if the dialogue gets bigger, and if some story logic gets added to the mix? Let’s take a look, shall we?
We have a good overview over the dialogues in articy. Besides being bigger, both have a branching structure. And they employ something we have not dealt with in this series before: Story logic. Both use a Boolean variable to check if the player triggered the dialogue already and if yes starts it with a slight variation.
Also we have a branch option in dialogue 2 in form of a reaction point that only is available if we followed a certain path in dialogue 1, which we also check with a Boolean.
Let’s set up the final dialogues in Unreal. All we need to do is to select the NPC objects in the Outliner or the level itself and change the value of the Dialogue variable to Dialogue 1 for NPC 1 and Dialogue 2 for NPC 2.
What about the story logic? What to do we need to do to implement that in the Unreal project? Nothing, really. The Flow Player takes care of our global variables in the background right out of the box. Besides changing the reference for which dialogue to start we haven’t made a single change since last lesson. So let’s play the level and see what happens.
Before we actually click Play we go to the Settings (1) and open the Articy Global Variable Debugger (2). This will display all variables from the articy project and gives us a live view to any changes while we play.
I also display the articy Flow, so we have a better understanding where we are in the dialogue. I expand the view for the Game State variable set in the global variables debugger window, then I interact with NPC 1.
Right before the hub we have an instruction in the output pin of the node, in which we change the value of visitedDialogue1 to true. In the database panel you will notice that this change only happens when we actually choose one of the options. This is because the Flow Player is pausing on the Dialogue Fragment where Kirian asks if he can help us, until we select an option and with that start the Flow Player again. Only then the instruction gets actually processed.
If during our conversation with Kirian we select the “no idea” branch, we get a tip what we could ask the Oracle later, and with that assigning a true value to the gotTip Boolean.
The dialogue ends and we can go and talk to the red NPC, the Oracle. Again we are setting a bool in an output pin to be able to check for a repeated triggering of the dialogue later.
If we are about to end the dialogue we get to a reaction point, where a condition checks if the player received Kirian’s tip in dialogue 1. If you skipped the branch or maybe talking to him entirely the dialogue ends, if you got the tip then you get some additional information from the Oracle. This happens automatically depending on variable value, without any player input.
If we interact with either NPC again, we automatically follow the second branch of the dialogue flow, skipping the introductory chit-chat. Because the value of the visitedDialogue variable is now true, this makes the second branch the only valid option to follow.
All this happens without us having to add anything to any blueprint!
There is one more thing I’d like to explain. You might have noticed it already when we looked at the dialogues in articy. When setting up the button functionality back in lesson 3 we determined that a branch button is created for a following dialogue fragment and if we don’t have any of those we create a close button instead. But if we look at our current dialogue, we have elements in there that are clearly not Dialogue Fragments, like a Jump (1), a Hub (2), or a Condition node (3).
Still the dialogue does not end when getting to these points. Why not? In lesson 3 I stated “We know a dialogue is supposed to be over if there is no following dialogue fragment.” We check for the branch target, but this does not necessarily have to be the very next element, like we see it in the flow. It again depends on the On Pause settings we did in the Flow Player component. We have only selected Dialogue Fragments and Dialogues for the Flow Player to pause on, that means on this flow layer only Dialogue Fragments will appear as valid stop targets.
If we are at the position depicted in the below image (1), the Condition node would be processed (2) to determine which branch to follow, in a process called forecasting, but as we don’t stop on these nodes the forecasting would continue and depending on variable value either arrive at the next Dialogue Fragment (3), which would create a branch button and with that continue the dialogue; or get to the end of the Dialogue node (4), which means we get a close button now, because of the way our dialogue in articy and our On Branches Updated event is set up. Remember, we do a cast to a Dialogue Fragment, so regardless if this dialogue node is connected to the following one in articy or not, the cast will fail, meaning no new branch button and as a result of that the creation of the close button, concluding the dialogue.
Process logic to the very end
There is still something I’d like to improve. You might have noticed the variable called testEnd in the Global Variable debugger earlier. The value of this variable gets changed in the output-pin of the very last dialogue fragment of dialogue 1. But wait a minute, you are probably saying right now, we went through this dialogue earlier until the end and the value of this variable did not change! And you’d be absolutely right.
I mentioned it a bit earlier when we watched the visitedDialogue1 variable change. The instruction in the out-put pin only get processed when the Flow Player ends its pause and continues its traversal. However, in this case the dialogue is about to end, that means the Flow Player does not go forward anymore. We need to make sure that the entire node gets processed before we end, to not potentially lose any data.
Fortunately we can do that with a small update to the End Dialogue function in the Demo Game Mode blueprint. We get a reference to the Articy Flow Player and use it as the target for a Finish Current Paused Object function. This function does exactly as advertised with its name, the object the Flow Player is currently paused on gets processed in its entirety. That means the variable change will happen before the dialogue ends.
Let’s take a look if this is really the case. Perfect!
Goal of tutorial series
With that we have achieved the goal we set for ourselves at the start of this tutorial series. We have set up a simple dialogue system to properly display dialogue we imported from articy:draft in the custom dialogue UI within our Unreal project. Now writers and designers can make changes in articy and are able to check out these changes in the engine very easily.
I can do things like updating some text in this dialogue fragment (1), adding an entire new branch to the dialogue (2), or rename an entity, and with – literally – a few clicks this updated data gets imported to our Unreal project where it can be tested and verified.
Please note that changes to templates, adding variables, or other potentially generated types will trigger a rebuild and we all know that those can take some time in Unreal.
Improving NPC interaction
There is one final thing I’d like to add to our dialogue system functionality and that is a check if the NPC the player interacts with actually has dialogue. At the moment interacting with an NPC without dialogue reference opens the dialogue UI with the default line, or the dialogue of another NPC if we interacted with it before. Not the best behavior.
If the NPC’s Dialogue variable is not filled with an Articy Reference interaction should not be possible in the first place. This is more of an Unreal thing than articy functionality, but anyway it will improve our little dialogue system.
We will make this update in the Player Character blueprint in the Interact Check function.
After the successful check if the target implements the interact interface we add a cast to BP_NPC on the Out Hit Hit Actor. From there we get the Dialogue variable, then get its Object ID and check if this ID is valid. If yes we continue this Branch and the interaction prompt is shown. If there is no valid ID, for example because we haven’t assigned any dialogue to the NPC in question the false output of the branch leads to the lower branch with the result that no interaction prompt appears and no actor is passed to the return node, which means that no interaction is possible.
Works like a charm. But before I forget I will give the Oracle her dialogue back.
What else can we do with articy and Unreal? A lot more! You could take care of items, use articy location data, access templates… Basically all data you create in articy, you can bring over to Unreal and make use of it there.
For a more hands-on experience you can take a look at the Maniac Manfred demo project. It consists of projects for both articy and Unreal and shows more advanced use cases for the Importer. You can download it here.
To stay informed in all topics related to articy, for news about the games industry, or to get in touch with us, visit our website or follow us on social media. We love to hear from our users!