Integrated Dialog Editor

Purchase ]
Documentation

Hey there folks. I’d like to share something I’ve been working on for the past few months with you. Hopefully, given enough interest and a bit of time this tool will find its way to the marketplace.

Inspiration
This tool came forth from a personal gripe of mine that it is currently impossible to properly create branching dialogs in Unreal Engine. Doing it in Excel or some other “linear” editor makes it a gigantic pain when dialog choices mean that you can jump around different lines or even loop back. And let’s not mention any more complex stuff. Thus, after a lot of research, some tinkering and a lot more work, I am proud to present my Integrated Dialog Editor.

Features

Important: Before reading on I’d like to clarify that this is a system for creating dialog data only. There are no UMG components or logic to actually display this data to the player. The dialog system is used to create and “traverse” dialogs. It is the developers choice how to display and use this data in their games.

Create complex branching dialogs easily using the familiar Unreal Engine graph editor. Dynamic branching is controlled via Flags that can be driven by outside events. Special conduit nodes work in a similar fashion to Select nodes in BehaviorTrees, in that the first node whose flag is set will get executed. Flags can be set per dialog or on a global level.

[SHOT]http://i.imgur.com/M5faHVc.png[/SHOT] [SHOT]http://i.imgur.com/X3S4Pn2.png[/SHOT]

Each dialog line can be fully customized with a ton of integrated data. You can associate speakers, sound cues and animations to dialog lines, as well as add any number of dialog choices. The availability of lines as well as choices in lines is dictated by the set flags. Similar to FText::Format, you can use format wildcards in dialog text and feed values in later on when you start the dialog. Dialog speakers allow you to define all the actors of your game and associate various properties with them. You can assign a skeleton that will be used with this speaker. This will in turn be used to filter the animation list for the dialog lines that use this speaker. Conduits can be nested to control the flow of the dialog as complexly as you need it to be. Since these dialogs tend to loop back quite a bit, redirect nodes are fully supported.

[SHOT]http://i.imgur.com/mm4RAhe.png[/SHOT] [SHOT]http://i.imgur.com/irHviuB.png[/SHOT] [SHOT]http://i.imgur.com/ft44c4d.png[/SHOT]

When starting the dialog from Blueprint (or code) you can fully customize all initial parameters as well as feed in data for wildcards. All of this can be done at any point during the dialog as well of course. It is important to note that it is fully possible to retain the state of a dialog if it’s canceled before it ends. This can be useful when it’s important to save and restore a dialog state such as with visual novels or Ace Attorney-style games.

[SHOT]http://i.imgur.com/my2kXd8.png[/SHOT] [SHOT]http://i.imgur.com/hYe4Juk.png[/SHOT] [SHOT]http://i.imgur.com/Bo1ZoRt.png[/SHOT]

Flags can be set or unset via the API dynamically but it is also possible to associate functions with flags to have them be queried automatically when the dialog system encounters the specified flag. These functions can be as complex as you need them to be.

[SHOT]http://i.imgur.com/fAy3ZCj.png[/SHOT]

You can hook into all of the important events and drive any and all of the game logic you can think of based on what happens in dialogs (Camera transitions, monster spawns, level loads etc.)

Everything in the plugin is using FText and as such fully supports localization.

In addition to these, there’s an optional system to assist with creating dialog camera transition. The system works in four steps. All of the techniques shown can be used partially, or not at all. This is completely optional.

1. Set up the type of scene for a particular dialog line

[SHOT]http://i.imgur.com/iZ3WeLT.png[/SHOT]

During dialogs, no matter how big or small, different characters (singular and plural) are being focused via different camera shots. These can be set per-line and can have the following variations:

  1. None - Disabled. The scene system has absolutely no performance overhead if not used.
  2. Any - Any scene that contains the current speaker and is associated with this dialog will be eligible. Picked at random.
  3. Speaker - Get the focus shot of this speaker. More on this in a minute.
  4. Player - Get the focus shot of the player character. Same as above.
  5. Matinee - Play a matinee during this line.
  6. World - Get a world shot that contains all speakers specified in a list. If there is no such shot, it will fall back to “Any”. I thought about renaming this “Group” but really, you can set it to show anything, focus on furniture or some mountains etc.
  7. Labeled - Get a specific named shot, marked by a FName label.

2. Set up speaker shot configurations
Most games that have dialogs (namely RPGs) usually have one common camera angle / position that the camera focuses on when the player talks to NPCs. To this end I’ve set up a new asset type called SpeakerCameraSettings.

[SHOT]http://i.imgur.com/ygTwLhg.png[/SHOT]

This is used to define the socket and offset of where the camera will be positioned, and the socket and offset the camera will be look at. This can then be reused in all your NPCs. Note that the set up is an array. If the two trace settings are turned on, when selecting a position, the system will go sequentially through the array and select the first setting that passes the tests (or has both tests turned off). This is to be able to define several presets (like over the shoulder left, over the shoulder right etc.) and avoid the camera clipping through walls if you have wandering NPCs.

3. Mark actors in your world as speakers

To actually mark actors in your world as speaker, you attach the new SpeakerSettingsComponent to them.


This simply tells the system which speaker this actor is, and what configuration to use for this speaker.

There are BP exposed functions to change both of these at runtime. For example, you could have a telephone that you can “talk to” and it ends up being several speakers.

4. Create World shots

Last but not least, to facilitate static shots, group shots and such, you can use the new DialogSceneCameraActor.


This camera actor can be used in several dialogs and the list of speakers in it can be adjusted at runtime. Currently I am working on making it automatically check which speakers are in view of this camera, although this check might end up being expensive and is of dubious usefulness. Perhaps a more useful feature would be to have the camera rotate to focus on the current speaker.

Either way, in addition to the speakers you can also tell this particular camera to use a matinee. What happens in that case is that a matinee will be played instead of switching to this camera. However, it is of note that in your dialog lines, if the scene is set to Matinee you can also define what scene will be used AFTER the matinee, in case the player hasn’t advanced to the next line.


If this isn’t set, and the matinee finishes playing, the camera will switch to the camera actor that started the matinee.

Incoming Features

  1. Sequencer Support
  2. Additional Documentation
  3. (Done!) Automatic Sound Cue playback
  4. (Done!) Binding Event Flags via C++

Backlog

  1. CSV Import & Export
  2. Collapsing / expanding parts of the graph
  3. Line Node Prettify

Known Bugs

  1. Text in dialog nodes flickers if it’s too long

Right now I am focused on debugging and polishing the core features; making sure everything is as user friendly as possible. If any other features come up internally or are requested I’ll attempt to work them in before moving onto the marketplace submission

If you have any questions, suggestions or comments, I’ll be more than glad to read them! Let me know in this thread!

FAQ

Q: Alright but what about Slate / UMG? What do I do with this data?
A: As I said earlier, this is data only. It handles the flow of the dialog based on flags and whatnot under the hood. It is up to the specific game to implement their UI and a way to display the data. For example, when you talk to an NPC, you’d pass his dialog object to the HUD, bind all of the events for that dialog and show your UMG widgets that display the speaker name / dialog text etc. when the dialog starts, change the text after you call MoveToNextLine and hide it all inside of OnDialogEnd. The example project contains a simple set of widgets that you can use as a reference point.

Q: How long will you maintain and update the plugin?
A: This plugin started out of necessity as I needed a dialog editor for my studio’s project. That project will be developed for the next few years and I will be updating and perfecting the plugin in a real-world environment to make sure it’s as awesome as it can be!

Best regards,
Damir H.

Woah! This is a very interesting take on dialog that I have never seen before!! The design is the same as my blueprints but this is super custom type? Dang that’s rad!!

Looking good Damir. Yeah, trying to make sense of the asset editor code takes a lot of effort!

I’ve been working on a kind of quest editor and have considered whether I might eventually need to create a dialogue editor to go with it, since like you I don’t think the existing options using data tables can cut it for anything non-trivial. This looks very promising though.

One thing you don’t appear to have mentioned - any plans or thoughts on dynamic dialogue alterations? For example, enabling/disabling sections of the graph at runtime, or hooking up nodes/choices to condition callbacks so you can control the NPC and player choices based on changing game state. I think this would be fairly important for most games, though I realize it’s also not so straightforward to get right. I coded up what was meant to be a very basic dialogue system (using data tables) for my quest system demo environment, but it quickly spiralled in complexity when I wanted dialogue options to change based on quest status.

One other thing. I don’t want to discourage you from releasing for free if that’s your intention, but in case it would help sustain your development, plugins have been accepted for submission on the marketplace for a few months already, and the first ones are likely to be released in the next month or so. In fact they are even accepting free marketplace plugins now too.

Hey there, thanks for the feedback! You’re right I forgot to mention dynamic alterations, those will most definitely be in there. Which means I will have to be throwing in some sort of variable system whether I like to or not. I did actually code this in BP so I know what’s required.

And awesome news on the marketplace stuff. Gonna look into that.

I’ve given this some thought and in the end decided to go against a full fledged variable and condition binding approach, simply because this needs to be usable by a person who doesn’t know the first thing about what a bool is, let alone creating conditional branching in a dialog. This, and the fact that creating a full-fledged BP editor is a bit more than I can chew right now, resulted in me opting in for a “flag” system. You can assign a flag to each dialog line and dialog choice. If that flag is not set, that line / choice will not be available. You’ll be able to adjust these flags via the BP / C++ API as the dialog starts and progresses.

Also I’ve added support for FText formatting. You can just add {TheseThings} just like you would with normal FText and via the API you can populate them with various values.

And one last update for today:

As you can see there are quite a few new properties. Most of these are self-explanatory, and the voice actor directions are copied straight over from the DialogueWave assets. However, you’ll notice that there are two different animations. The idea behind this is that characters might have full-body animations, but they might also walk around and just have a facial animation. These will be passed on via the OnLineStart event and can then be applied in an animation blueprint.

This is a bit of an obscure bit of info but you won’t have to set all of these dialog animations up in your animation blueprint ahead of time. If you play a state you can check the “As Pin” checkbox and you’ll be able to plug in a variable into that state. That way you can read the animation from the dialog and play it in a single state, whichever animation it is.

Also, we now have dialog speakers!

Of special note is the Skeleton property, which, if set, will filter the animation lists in the dialog editor.

This looks brilliant, great job :)! You talked about cameras and matinees in the first post so, just to make sure, I’d like to ask if you can just keep the normal, player-controlled ingame camera active during these dialogues.

Of course. Any camera adjustment would have to be done explicitly.

Hey there guys! I have made some huge improvements to the plugin and I’ve updated the OP. Since I could not get any information about C++ plugins on the Marketplace I am releasing the plugin on Gumroad. It can be found . A full documentation document will be published shortly.

Thanks for all your support!

Best regards,
Damir H.

Wow, this is awesome! Great job Damir! :smiley:

Hey DamirH,

Looks pretty good to me.

Tried to login to Gumroad with facebook, but then it asked me if it could manage my facebook pages so I said no, now I just get a 404 from your link?

Hmm, don’t know honestly, I haven’t used gumroad extensively. Maybe try opening my profile page, should be a link to the plugin there? Alternatively, open up incognito mode to clear cookies and stuff, then try from there.

And one last update for today - I’ve finished the first quick version of the documentation. It’s not comprehensive but should get you off the ground. I’ve also updated the files on Gumroad to 4.10.4 (Was 4.9.2 before).

Two new features have been added:

  1. Automatic Sound Cue playback
  2. Binding Event Flags via C++

Since I am working on the plugin more or less constantly I will be able to push updates rather often, however I’d prefer not to spam people too much with updates so I’ll make it periodical.

Hey guys,

Just to inform everyone that sequencer support is on its way as I’ve finally upgraded my engine version. Thanks for the patience!

Update 1.0.3


-New Feature: Automatic Sound Cue Playback
-New Feature: Binding Event Flags via C++
-New Feature: Automatic line advancement with variable delay - In the advancement rollout of the basic Dialog Line settings you can now set a delay to tell the system to automatically advance to the next line.

-Improvement: All of the properties in the dialog line settings are now commented
-Improvement: Crashes due to invalid function parameters (i.e. passing a null dialog to MoveToNextLine) are now more descriptive and user-readable.

-Bug Fix: Having a dialog line or choice lead to a line, then removing that link would cause the dialog line or choice to either not remove the link, switch the link to some other random line in the dialog, or point to an invalid line causing a crash

-Important: The BP function “Get Dialog Manager Checked” has been deprecated in favor of the neatly named “Get Dialog Manager”.
-Important: Due to changes to the event binding code, the “Bind Event To Flag”, “Bind Events To Flag”, “Bind Global Event To Flag” and “Bind Global Events To Flag” blueprint functions will throw errors upon updating and need to be placed again. Apologies for the inconvenience.

Good work :slight_smile: I was thinking of a node based dialog system and happily someone else (namely you) comes along and makes one :smiley: purchased, but I haven’t had a chance to try it yet.

Nice work!

( Now I can see a lots of eroge incoming . . . :rolleyes: )

Update 1.0.4


-Bug Fix: Fixed a crash that occurred when ADialogManager::EndDialog() was called from either a OnDialogLineStart, OnDialogLineEnd, OnDialogEnd or OnGlobalDialogEnd callback (possibly more). The OnDialogEnd and OnGlobalDialogEnd delegates now have an additional bForceEnd boolean to distinguish between a natural finish and a forced EndDialog() finish. Ending the dialog via the function now queues the ending, meaning that instead of immediately finishing, it will finish after the next MoveToNextLine() call, regardless of whether or not there’s anything hooked up the current line. The EndDialog() function has been deprecated in favor of QueueEndDialog as the name clarifies the intent of the function better.

when will this be recompiled for 4.11 i cant open project without disabling the plugin, thanks for this awesome tool!