The Dialogue System has a comprehensive API for programmers. For visual scripting, the Dialogue System supports several visual scripting systems including Playmaker Support, Makinom Support, and Unity's Visual Scripting Support package.
This is the Dialogue System for Unity's Scripting Reference. The API reference is integrated with this manual. Click the buttons above to view Namespaces, Classes, and Files, or use the search bar in the upper right.
A common use of scripting is to integrate with other code, either your project's custom code or other Asset Store assets. For general integration tips, see General Integration Tips. The Dialogue System includes integration packages for many assets. For the list of assets and their integration instructions, see Third Party Integration.
The use of assembly definitions (asmdefs) is optional. Since the Dialogue System imports into Plugins
, it compiles separately from your project's code, so it won't impact compile times of your code.
If you do want to use asmdefs, import Plugins/Pixel Crushers/Dialogue System/Scripts/DialogueSystemAssemblyDefinitions.unitypackage. This will import four asmdef files: PixelCrushers, PixelCrushersEditor, DialogueSystem, and DialogueSystemEditor.
If you import the Dialogue System asmdefs and enable integrations with packages that use asmdefs, you must also add references to those asmdefs to the Dialogue System asmdefs. Since we can't know ahead of time what integrations you will enable, it's not possible to add those asmdef references ahead of time. However, we've added references to some of the most commonly-used Unity packages: Addressables, Cinemachine, Input System, TextMesh Pro, and Timeline. If those packages are not installed in your project, the references will be ignored.
Addressables note: DialogueSystem.asmdef has a reference to Unity.Addressables.Editor. This reference will only be used in the Unity editor. It won't be compiled into builds. The Dialogue System's PreviewUI script needs to use some editor-specific code when previewing addressable audio clips in the Timeline editor. This gets compiled out in builds, though.
All Dialogue System source code is contained within the namespace hierarchy PixelCrushers.DialogueSystem
.
Pixel Crushers Common Library source code is in the PixelCrushers
namespace.
LuaInterpreter is contained in the namespace Language.Lua
.
The Dialogue System uses a Model-View-Controller (MVC) architecture:
MVC | Description |
---|---|
Model | State of the dialogue database, Lua, and active conversation. |
View | Dialogue UI and cutscene sequencer. |
Controller | Mediates between the model and the view. |
However, the entire MVC architecture is managed by the PixelCrushers.DialogueSystem.DialogueManager. To control the Dialogue System you'll generally only need to use DialogueManager methods.
For more information about the relationship between dialogue database fields and Lua values, see Dialogue Database Fields and Lua Values.
The Templates ► Scripts folder contains templates that you can copy to create your own implementations of dialogue UIs, bark UIs, sequencer commands, and persistent data recorders.
The Dialogue System supports a number of scripting define symbols such as TMP_PRESENT to enable support for TextMesh Pro and USE_TIMELINE to enable support for Timeline. You can view and enable or disable these symbols in the Dialogue System's Welcome Window. The exception is LATEUPDATE_MESSAGES:
The ->Message
syntax in Cutscene Sequences allows you to send a sequencer message when a sequencer command has completed. It normally sends the message as soon as the command completes. If you want to delay the message until LateUpdate (e.g., after animation updates), manually add the scripting define symbol LATEUPDATE_MESSAGES
. To add it, select menu item Edit > Project Settings > Player > Other Settings. Add it to Scripting Define Symbols.
Below are some of the most commonly used script methods. Each class below has many other useful methods, too. These are just the methods that you're most likely to use if you're writing scripts to work with the Dialogue System.
PixelCrushers.DialogueSystem.DialogueManager.Bark:
PixelCrushers.DialogueSystem.DialogueManager.BarkString:
PixelCrushers.DialogueSystem.DialogueManager.GetLocalizedText:
PixelCrushers.DialogueSystem.DialogueManager.PlaySequence:
PixelCrushers.DialogueSystem.DialogueManager.SendUpdateTracker:
PixelCrushers.DialogueSystem.DialogueManager.ShowAlert:
PixelCrushers.DialogueSystem.DialogueManager.StartConversation:
PixelCrushers.DialogueSystem.DialogueManager.StopConversation:
PixelCrushers.DialogueSystem.DialogueManager.instance Points to the current instance of the PixelCrushers.DialogueSystem.DialogueSystemController: component, which is the MonoBehaviour for which DialogueManager is a wrapper.
PixelCrushers.DialogueSystem.DialogueSystemController.isInitialized PixelCrushers.DialogueSystem.DialogueSystemController.initializationComplete: DialogueSystemController initializes itself in Start(). When complete, it invokes the initializationComplete event, which your code can hook into. The isInitialized property indicates that initialization is complete. You can use initializationComplete or isInitialized to know when the DialogueSystemController is fully initialized in your own Start() methods since it's possible that your own Start() method could start before the DialogueSystemController's Start() method.
PixelCrushers.DialogueSystem.DialogueLua.GetVariable:
PixelCrushers.DialogueSystem.DialogueLua.SetVariable:
PixelCrushers.DialogueSystem.QuestLog.GetQuestState:
PixelCrushers.DialogueSystem.QuestLog.SetQuestState:
PixelCrushers.DialogueSystem.QuestLog.GetAllQuests:
PixelCrushers.SaveSystem.SaveToSlot:
PixelCrushers.SaveSystem.LoadFromSlot:
PixelCrushers.SaveSystem.LoadScene:
The Dialogue System has an extensive API that allows you to control every aspect. The API reference is integrated with this manual. To search for something, enter it in the search bar at the upper right of this page, or click the Classes tab at the top of the page.
You can use the attributes below in your own scripts.
Use the [ConversationPopup]
attribute to turn a string into a conversation popup. It has two optional bool parameters:
Use the [DialogueEntryPopup]
attribute in your class definition to turn an int into a dialogue entry ID popup. NOTE: This attribute will only work if your script also has a string variable named 'conversation', 'conversationTitle', 'conversationName', 'Conversation', 'ConversationTitle', or 'ConversationName'. This is how the dialogue entry popup knows which conversation's entries to show. This attribute also does not support lists of serialized classes.
Use the [QuestPopup]
attribute in your class definition to turn a string into a quest popup. It has an optional bool parameter to show a database selection field.
Use the [QuestEntryPopup]
attribute in your class definition to turn an int into a quest entry popup. NOTE: This attribute will only work if your script also has a string variable named 'quest', 'questTitle', 'questName', 'Quest', 'QuestTitle', or 'QuestName'. This is how the quest entry popup knows which quest's entries to show. This attribute also does not support lists of serialized classes.
The [QuestState]
attribute changes the quest state popup to use lowercase letters so it matches the case used in Lua.
Use the [ItemPopup]
attribute in your class definition to turn a string into an item popup. It has an optional bool parameter to show a database selection field.
Use the [ActorPopup]
attribute in your class definition to turn a string into an actor popup. It has an optional bool parameter to show a database selection field.
Use the [VariablePopup]
attribute in your class definition to turn a string into a variable popup. It has an optional bool parameter to show a database selection field.
Use the [LuaConditionWizard]
and [LuaScriptWizard]
attributes in your class definition to turn a string into a Lua wizard field. This allows you to assign Lua code to the string using the Point-and-Click Lua wizards.
The Dialogue System sends several useful messages that your scripts can handle. It also has corresponding C# events that you can hook into.
You may also find it convenient to hook up events visually in the inspector using the Dialogue System Events component.
Event | Description |
---|---|
DialogueManager.instance.initializationComplete | Dialogue System has completely initialized, including loading the initial dialogue database and registering Lua functions. |
DialogueManager.instance.conversationStarted | Conversation has started. Parameter is primary actor's transform. |
DialogueManager.instance.conversationEnded | Conversation has ended. Parameter is primary actor's transform. |
DialogueManager.instance.overrideGetLocalizedText | Assign to override the default GetLocalizedText() method. |
Sequencer.receivedMessage | Called by a Sequencer object when it receives a sequencer message. |
The Dialogue System sends these messages to the participants involved:
Message | Recipient | Description |
---|---|---|
OnConversationStart(Transform actor) | Participants, Dialogue Manager & children | Sent at the start of a conversation. The actor is the other participant in the conversation. |
OnConversationEnd(Transform actor) | Participants, Dialogue Manager & children | Sent at the end of a conversation, after the dialogue UI has closed. The actor is the other participant in the conversation. |
OnConversationCancelled(Transform actor) | Participants, Dialogue Manager & children | Sent if a conversation ended because the player pressed the cancel key or button during the player response menu. |
OnPrepareConversationLine(DialogueEntry) | Dialogue Manager only | Sent prior to evaluating a dialogue entry's links and preparing it to be spoken. Note: Also sent prior to preparing a bark. |
OnConversationLine(Subtitle subtitle) | Participants, Dialogue Manager & children | Sent just before a line is spoken. See the PixelCrushers.DialogueSystem.Subtitle reference. Your method can modify the subtitle before it's displayed. |
OnConversationLineEnd(Subtitle subtitle) | Participants, Dialogue Manager & children | Sent at the end of a line, including if the line is cancelled. |
OnConversationLineCancelled(Subtitle subtitle) | Participants, Dialogue Manager & children | Sent if the player pressed the cancel key or button while a line was being delivered. Cancelling causes the Dialogue System to jump to the end of the line and continue to the next line or response menu. |
OnConversationTimeout() | Dialogue Manager only | Sent if the response menu timed out. The DialogueSystemController script handles timeouts according to its display settings. You can add your own scripts to the Dialogue Manager object that also listens for this message. See Example: Custom Timeout Handler for an example. |
OnConversationResponseMenu(Response[] responses) | Dialogue Manager & children | Sent before showing a response menu. See the PixelCrushers.DialogueSystem.Response reference. Your method can modify the content of the responses. |
OnLinkedConversationStart(Transform actor) | Participants, Dialogue Manager & children | Sent when an active conversation follows a cross-conversation link to a different conversation in the dialogue database. |
OnTextChange(UnityEngine.UI.Text) | Only Unity/Standard UI Dialogue UI | Sent when a Unity UI Dialogue UI Text element changes |
Message | Recipient | Description |
---|---|---|
OnBarkStart(Transform actor) | Participants, Dialogue Manager & children | Sent at the start of a bark. The actor is the other participant. |
OnBarkEnd(Transform actor) | Participants, Dialogue Manager & children | Sent at the end of a bark. The actor is the other participant. |
OnBarkLine(Subtitle subtitle) | Speaker, Dialogue Manager & children | Send at the start of a bark before the line is barked. Your method can modify the subtitle before it's barked. |
Message | Recipient | Description |
---|---|---|
OnSequenceStart(Transform actor) | Speaker & listener | Sent at the beginning of a cutscene sequence. The actor is the other participant. (Sequences can have an optional speaker and listener.) |
OnSequenceEnd(Transform actor) | Speaker & listener | Sent at the end of a sequence. The actor is the other participant. |
OnSequencerMessage(string msg) | Dialogue Manager | Sent when sending a sequencer message. |
The sample script below logs conversation activity. Add it to an actor such as the player.
Notes:
DialogueManager.LastConversationStarted
records the last conversation that was started, or the current conversation if a conversation is active.The sample script below restarts the conversation at the beginning if the response menu times out. Add it to the Dialogue Manager. It works best when the Dialogue Manager's Input Settings > Response Timeout Action is set to Custom.
Quest log windows broadcast the following messages to the Dialogue Manager when the player toggles quest tracking. You can add a script to the Dialogue Manager or a child object that handles the message – for example, turning on a gameplay HUD.
Message | Recipient | Description |
---|---|---|
OnQuestStateChange(string title) | Dialogue Manager & children | Sent when a quest state or quest entry state changes via the QuestLog class and/or Lua functions SetQuestState and SetQuestEntryState . |
OnQuestEntryStateChange(QuestEntryArgs args) | Dialogue Manager & children | Sent when a quest entry state changes. QuestEntryArgs is a struct with two fields: (string)questName and (int)entryNumber. |
OnQuestTrackingEnabled(string questTitle) | Dialogue Manager & children | Sent when tracking is enabled. |
OnQuestTrackingDisabled(string questTitle) | Dialogue Manager & children | Sent when tracking is disabled or a quest is abandoned. |
You can also hook into several QuestLog delegates:
Message | Recipient | Description |
---|---|---|
OnShowAlert(string message) | Dialogue Manager & children | Sent when DialogueManager.ShowAlert() is called. |
OnDialogueSystemPause() | Conversation participants, Dialogue Manager & children | Sent when DialogueManager.Pause() is called. |
OnDialogueSystemUnpause() | Conversation participants, Dialogue Manager & children | Sent when DialogueManager.Unpause() is called. |
OnUse(Transform actor) | Targeted Usable | Sent by Selector and Proximity Selector. |
Normally, you will add conditions on a dialogue entry using its Conditions field, specified in Lua code. However, if you need to perform extra checking outside of Lua, you can set the Dialogue Manager's IsDialogueEntryValid
delegate. This is a C# method that returns true
or false
. If it returns true
, the dialogue entry is considered for use in the current conversation.
Example:
Here's a real world example of IsDialogueEntryValid
. It's in a subclass of StandardDialogueUI, but you could put it anywhere.
If you need to update the available choices in the player response menu while the response menu is already being displayed, call:
This updates the responses for the current state of the current conversation. For example, say your player is a shapeshifter in a fantasy game. When she talks to an NPC while in cat form, the response menu may contain choices specific to her cat form. But if she transforms into a dog while the response menu is displayed, call DialogueManager.UpdateResponses()
to remove the cat-specific choices and add the dog-specific choices.
A DialogueDatabase consists of Actor, Item, Location, Variable, and Conversation, objects that are all subclasses of the Asset class. Conversations contain DialogueEntry objects that are not a subclass of Asset but are nevertheless structured similarly.
These objects have a fields
list, which is a list of Field objects. You can use static methods in the Field class such as Field.LookupValue to look up values from a fields
list.
The Asset class – which Actors, Items, Locations, Variables, and Conversations inherit – also have helper methods such as Asset.LookupValue to simplify your code so you don't have to access the fields
list directly.
At runtime, the Dialogue System loads values from your dialogue database asset into an in-memory version referenced by DialogueManager.masterDatabase. Then it loads the values from the dialogue database into a Lua virtual machine where the current values can be checked and changed during play. The important distinction is that dialogue database values (e.g., fields) should be treated as read-only during play. To check or change their current runtime values, use Lua.
The simplest way to check and change Lua values is to use the DialogueLua class. To work with quests, use the QuestLog class, which is a helper class built on top of DialogueLua that provides simpler functions for working with quests.
This section contains information on manually creating and adding additional dialogue databases at runtime in a script.
Note that in addition to manually creating database contents, you can also import articy:draft XML and Chat Mapper XML at runtime. (See Import & Export.)
When creating a database, use the Template class. If the script runs in the editor, you can use TemplateTools.LoadFromEditorPrefs() to get a Template class that uses any template fields you've set up in the Dialogue Editor's Templates section. Otherwise use Template.FromDefault() like the example below. This example creates a new database and adds a conversation with a START node and one actual node:
If you want to add extra fields to something in the database, use Field.SetValue() like this:
Everything inside a database has an internal ID number: actors, items/quests, locations, variables, conversations, and dialogue entry nodes. They don't have to be sequential, but they do have to be unique among their type. That is, there should only be one actor with a specific ID, one conversation with a specific ID, etc. (But it's fine to have an actor with ID 42 and a conversation with ID 42 since they're different types.)
Internally, the Dialogue System looks up these resources by their IDs. If the initial database has a conversation with ID 42 and your newly-added database also has a conversation with ID 42, it won't know which one to use.
If you create multiple databases at design time, you can use the Unique ID Tool editor window to reassign IDs to resolve conflicts.
But if you're creating a database at runtime, you can't use this editor window. Instead, there are two ways to resolve the conflicts:
There are several ways to customize the Dialogue Editor window:
Example template script:
Unity supports running in batch mode in the Unity editor and Standalone builds: https://docs.unity3d.com/Manual/CLIBatchmodeCoroutines.html
The Dialogue System normally uses WaitForEndOfFrame operators, which are not supported in batch mode.
To use the Dialogue System in batch mode, define the scripting symbol BATCH_MODE
. This will replace all yield return WaitForEndOfFrame
operations with yield return null
.
<< Welcome to the Dialogue System for Unity! | Import & Export >>