Skip to content

[WIP] Dialogue System Example Blueprint Implementation [Deprecated]

Implementation Overview

  • This is somewhat outdated now, the project this guide was based off of has been updated to be more modular using components and also handles player choices. This guide is being left as a reference and may be updated in the future.

The goal is to create a functional dialogue system using the ThirdPerson template where each individual character contains their own dialogue state machine.

The player should be able to interact with NPCs to start a dialogue.

Once implementation is complete only state machines will need to be used to design conversations just by editing text directly on nodes.

You can download the project used for this guide from GitHub. Project is newer than this guide!

Blueprint Prerequisite

We will need to setup normal blueprints before creating our state machine implementation.

UMG Widget

The UMG widget is responsible for rendering the text to the user

  • Create a new UMG widget called DialogueUI for displaying the speaker name and the dialogue text body.
  • The textblocks should be variables.
  • Create a function DisplayText that sets the dialogue text and speaker text.
    • We use a function rather than binding because binding is less efficient.
  • In this example there is a vertical box which sets the maximum size for the dialogue text.
  • For assistance creating UMG UI please see the official UE documentation.

DialogueWidgetUMG DialogueWidgetGraph

Dialogue Manager

A global manager for accessing the dialogue UI. This is in the game mode for this implementation.

  • Open the ThirdPersonGameMode blueprint.
  • Add a new variable of type DialogueUI.
  • Create two functions, DisplayDialogueUI and CloseDialogueUI.
  • DisplayDialogueUI is responsible for creating the widget if it doesn't exist, adding it to the viewport if it isn't already there, and then returning the dialogue widget.

GameModeDisplayDialogue

  • CloseDialogueUI removes the widget from the viewport and clears the variable.

GameModeCloseDialogue

Base Character Blueprint

We're going to use a new base character blueprint as a parent between our NPCs and player characters to share common functions. You could use an interface for this as well, but most of this functionality just needs to be defined once on a base class.

  • Create a new blueprint extending the Character class and call it BaseCharacter.
  • Add a State Machine Component called SMDialogue. Leave the component settings default.
  • Create a member variable of type text CharacterName. You can default the value to NPC.
    • Create a pure function GetCharacterName with a return type of text which returns the CharacterName.
  • Create a member variable of type BaseCharacter with name CharacterInConversationWith.
  • Create an event dispatcher called ContinueDialogue.
  • Create a function NotifyCharacterInConversation that accepts a BaseCharacter argument and sets the CharacterInConversationWith

NotifyCharacterInConversation

  • Create a pure function IsInConversation that checks that the CharacterInConversationWith is valid and returns a bool.

IsInConversation

  • Create a function StartDialogue with a parameter of BaseCharacter.
    • This will call NotifyCharacterInConversation both for this character and the Other Character.

StartDialogue

  • Create a function StopDialogue which will notify both characters they are no longer in a conversation.

StopDialogue

Input Handling and Third Person Character

  • Add an input action to your project called Talk and assign it a key. InputActions

  • Reparent the ThirdPersonCharacter blueprint to use BaseCharacter.

  • Overload NotifyCharacterInConversation, call its parent, and stop movement if the other character is valid.

ThirdPersonNotify

  • Add a float variable TalkDistance and set the default to 150.0
  • Create a new macro FindCharacterToTalkTo.
    • This will trace for characters in the direction you are facing within the TalkDistance range and return a BaseCharacter on success.

ThirdPersonFindCharacterToTalkTo

  • Finally, in the event graph listen for the input action Talk. Here we want to either start the dialogue or call the Continue Dialogue event dispatcher of the other participant.

ThirdPersonFindCharacterInputActionTalk

State Machine Nodes

We need to create several node classes that will be reused in our dialogue state machine graphs. See the Pro Quickstart Guide for creating node classes in Logic Driver.

Base Dialogue Node (State Class)

It's worth creating an abstract base class for dialogue nodes so we can extend it for normal text nodes and eventually choice nodes. Our goal is to make this class effictively own the current dialogue segment, be reponsible for displaying the text, and determine when the state should end.

  • Create a state class called FSMNode_DialogueNodeBase.
  • Uncheck Register with Context Menu in class defaults so this node won't show up as placeable in the state machine graph.
  • Add a variable of BaseCharacter called Speaker type and make it public.
  • Add a variable of type SM Text Graph Property called DialogueText.
    • This is a special Logic Driver variable which creates formatted a text graph on the node.
    • It doesn't need to be made public, TextGraphProperties always display on the node.
  • Add an event dispatcher: GoToNextDialogue
    • We will use this to switch dialogue nodes.

Functions

Should Dialogue End
  • Create a Pure function with a bool return type called ShouldDialogueEnd.
  • For now just check if the state is an end state.

DialogueEnd

Handle Dialogue Continue
  • Create a normal function called HandleDialogueContinue
  • This is the normal operation to determine if we should go to the next dialogue or end.

DialogueContinue

Event Graph
  • The base graph will bind to the character's Continue Dialogue event dispatcher. When this event fires we will call Handle Dialogue Continue.
  • On State Start will display the dialogue UI and send it our speaker name. We also break the Dialogue Text to get the result.
  • On State End we check if the dialogue is over and close the UI if necessary.

DialogueEventGraph

Dialogue Node (State Class)

General dialogue nodes that display text. These will be what we place in the graph.

  • Create a state class that inherits from FSMNode_DialogueNodeBase called FSMNode_DialogueNode.
  • Check Register with Context Menu in class defaults.

Dialogue Transition (Transition Class)

Transitions will check if the previous dialogue node should exit.

  • Create a transition class named FSMNode_DialogueTransition.
  • Set CanEnterTransition to always return true.
  • In the event graph override events Event On Transition Initialized and Event On Transition Shutdown
  • Get the previous state, cast to FSMNode_DialogueNodeBase and bind to the event dispatcher we created earlier GoToNextDialogue. Make sure SetCanEvaluate is set to false on Initialize, and set to true when the event is called.
  • In the class defaults, add a behavior rule under Allowed Connections. Set the From State to use the state class of FSMNode_DialogueNodeBase. This will automatically place this transition when dragging from any type of dialogue node.

DialogueTransition