Logic & Lua

No scripting is required in the Dialogue System. However, the Dialogue System does offer a general-purpose scripting language called Lua that provides a very powerful method of controlling the flow of conversations, checking and changing quest states, and more. In most cases, you can use simple point-and-click menus.

The Dialogue System uses the data model established by Chat Mapper, another professional dialogue authoring tool commonly used in the industry. Information about all actors, items, locations, variables, and conversations is stored in Lua tables. You can control conversations by specifying Lua conditions and scripts, typically by using point-and-click menus. For those who are interested, the Chat Mapper manual has more background info about Lua and the tables that the Dialogue System uses, in the section titled Scripting with Lua.

Lua in the Dialogue System

At runtime, the Dialogue System treats your dialogue database as read-only. It loads the database values into Lua where the current values can be checked and changed during play.

You can use Lua in the following areas of the Dialogue System:

Point-and-Click Lua

In most places where you can enter Lua code manually (if you prefer), you can also click a '...' button to switch the field into point-and-click mode. In this mode, you can use dropdown menus without having to type any code:

Click '+' to add new conditions or actions. Click Revert to cancel or Apply to apply your selections, which will close the dropdown menus and write the Lua code for you:

Note: As a convenience, if variable names contain "." such as "Global.Temperature", the wizards will show them in submenus – for example, the dropdown will have a submenu named Global containing an item named Temperature.

How to Write Lua Code

If you prefer to write Lua code directly, you'll find that it's similar to C# or UnityScript. For more information on Lua, see www.lua.org. There are a few syntax differences to be aware of:

Operator C#/UnityScript Lua Lua Example
Not equal != ~= Quest["Kill_5_Rats"].State ~= "success"
Logical AND && and Variable["HasCoke"] and Variable["HasMentos"]
Logical OR || or (Actor["Player"].Age > 21) or Item["Beverage"].IsNonalcoholic
String concatenation + .. Actor["Player"].FullTitle = "Dread Lord " .. Actor["Player"].Name .. " of Skull Island"
if if(x==y) if (x==y) (blank space req'd) if (x == y) then foo() end
Comment // – This is a comment.

Special Exception: LuaInterpreter "and not"

The default Lua implementation that ships with the Dialogue System is LuaInterpreter. This is a fast, lightweight C# implementation of Lua. However, it does not parse one valid Lua syntax:

X and not Y

. You can work around this limit by modifying your syntax slightly or by switching to a different Lua implementation.

Note that Lua, like C# and UnityScript, is case-sensitive.

Checking Values

Here are some examples that you can use in a dialogue entry's Conditions field or the Condition section of a Dialogue System Trigger component.

Check Variable

Check if a Boolean variable has been set true (note the use of double equals "==" to test equality):

Variable["flippedSwitch"] == true

Check Quest State

Check if a quest is in a specific state:

CurrentQuestState("Kill 5 Rats") == "success"

Check Actor and Item Fields

Check if the player is at least 21 and has at least one beer:

(Actor["Player"].Age >= 21) and (Item["Beer"].Count > 0)

Assigning Values

Here are some examples of setting values. You can use them in a dialogue entry's Script field or in the Lua Code action of a Dialogue System Trigger

Set Variable

Set variables (note the use of single equals "=" for assignment):

Variable["spokeToKing"] = true;
Variable["Gold"] = Variable["Gold"] + 50

Set Quest State

Set a quest to a specific state:

SetQuestState("Kill 5 Rats", "active")

Combining Strings

Combining two strings (using Lua's '..' notation):

Actor["Player"].FullTitle = "Dread Lord " .. Actor["Player"].Name .. " of Skull Island"

Special Data & Functions

Special Tables

A table in Lua is similar to an array or dictionary in C# or UnityScript. The following Dialogue Systemspecific tables are available to your Lua scripts:

Table Description Example
Actor[] Two-dimensional table containing all actors. Actor["Player"].Age
Item[] Two-dimensional table containing all items/quests. Item["Anvil"].Weight
Quest[] An alias for the Item[] table.
Location[] Two-dimensional table containing all locations. Location["Starbase"].Description
Conversation[] Two-dimensional table containing all conversations, indexed by ID. Conversation[9].Title
Variable[] One-dimensional table containing user variables. Variable["Alert"] = "Hello!"

In this Lua code:

Actor["Player"].Age = 21

the string "Player" is the key or index. The Actor["Player"] part is the table element. This is sometimes called a record in Lua guides. The Age part is the field. The code above sets the player's Age field to 21.

Special Variables

The Dialogue System also manages these variables in the Variable[] table:

Variable Description
Variable["Alert"] Set to tell the Dialogue System display an alert message.
Variable["Actor"] The name of the actor in the current conversation (if any)
Variable["Conversant"] The name of the conversant in the current conversation (if any)
Variable["ActorIndex"] The actor's index in the Actor[] Lua table
Variable["ConversantIndex"] The conversant's index in the Actor[] Lua table

The variables Variable["Actor"] and Variable["Conversant"] contain the display names of the participants. The variables Variable["ActorIndex"] and Variable["ConversantIndex"] are the indices in the Lua Actor[] table. You can use them in your dialogue entries' Conditions and Script fields. For example, to check if the current conversant is at least 21 years old:

Actor[ Variable["ConversantIndex"] ].Age >= 21

Important Note About Table Indices

Table keys and field names are generically called indices. The Dialogue System follows a convention established by Chat Mapper:

In Chat Mapper tables, replace all space characters, hyphens, forward slashes, quote characters, and parentheses with underscores in indices.*

Here are some examples:

In the Dialogue Database In Lua
A variable named Kissed the Frog
Variable["Kissed_the_Frog"]
An actor named Mister Big
Actor["Mister_Big"]
The actor's Favorite Color field
Actor["Mister_Big"].Favorite_Color
A variable named Kiss/Kill
Variable["Kiss_Kill"]

Special Lua Functions

The Dialogue System adds several useful functions to Lua, including:

Chat Mapper Functions

These Chat Mapper functions are available in Lua to record statuses and relationship values. The descriptions of these functions come from the Chat Mapper documentation:

Status Functions

Chat Mapper can track a status that is defined between any two assets, which is referred to as a mutual status. To set or access a mutual status, use the following two functions:

  • SetStatus( Asset1, Asset2, "status value" )
  • GetStatus( Asset1, Asset2 )

Examples:

  • Dialogue Text: "Here you are -- apartment 3B. The rent's 200 credits a week."
  • Script: SetStatus( Actor["Player"], Location["Apartment_3B"], "Home" )

  • Dialogue Text: "*beep* Welcome home. I am your personal assistant robot."
  • Conditions: GetStatus( Actor["Player"], Location["Apartment_3B"] ) == "Home"

Relationship Functions

Chat Mapper can also track numerical relationship values between any two actors. Relationships can be used to control NPC responses based on a relationship value. These are the relationship fuinctions:

  • SetRelationship( Actor1, Actor2, "relationship type", value )
  • GetRelationship( Actor1, Actor2, "relationship type" )
  • IncRelationship( Actor1, Actor2, "relationship type", incrementAmount )
  • DecRelationship( Actor1, Actor2, "relationship type", decrementAmount )

Examples:

  • Dialogue Text: "Oh my! Those are some serious abs! *swoons*"
  • Script: SetRelationship( Actor["Princess"], Actor["Player"], "Lust", 50 )

  • Dialogue Text: "Jim will remember that. [-2 trust]"
  • Script: DecRelationship( Actor["Jim"], Actor["Player"], "Trust", 2 )

  • Dialogue Text: "Loan you $50? I don't think so. I wouldn't trust you with a single penny."
  • Conditions: GetRelationship( Actor["Jim"], Actor["Player"], "Trust" ) < 1

Unsupported Chat Mapper Functions

The Dialogue System does not support the Chat Mapper functions below, which have have no meaning outside Chat Mapper:

  • TrackVariable
  • TrackStatus
  • TrackRelationship

Other Functions

Alert Functions

To show or hide an alert message:

  • ShowAlert( message )
  • HideAlert()

ID To Name Functions

Variables of type Actor, Item, or Location store the ID of an Asset (Actor, Item, or Location). This is a number, not the asset's Name field. To convert an ID to a Name, use:

  • ActorIDToName(id)
  • ItemIDToName(id)
  • QuestIDToName(id)

ChangeActorName() Function

Use ChangeActorName() to change

  • ChangeActorName( actorName, newDisplayName )

where:

  • actorName is the actor's Name field.
  • newDisplayName is the new Display Name value.

Example:

ChangeActorName("Mysterious Stranger", "Mephistopheles")

Notes:

  1. If a conversation is active, the change will take visible effect in the Portrait Name the next time the actor speaks.
  2. There is also a C# version: DialogueManager.ChangeActorName().

Conversation Position Stack Functions

If you add the component Conversation Position Stack to your Dialogue Manager, it will make three new Lua functions available:

  • PushConversationPosition(): Saves the current conversation position on the top of a stack.
  • PopConversationPosition(): Removes the conversation position on the top of the stack and returns to it.
  • ClearConversationPositionStack(): Clears the stack.

You can use these functions to dip into side conversations and then return to the original conversation at the point you left it.

Note: If you use PushConversationPosition() in a group node, it will return to the node that preceded the group. This allows the preceding node (usually an NPC node) to play its subtitle and re-evaluation the group's conditions.

Quest Functions

To get and set quest states (described in more detail in Quests):

  • CurrentQuestState( questTitle )
  • CurrentQuestEntryState( questTitle, entryNumber )
  • SetQuestState( questTitle, state )
  • SetQuestEntryState( questTitle, entryNumber, state )

While you can technically set quest states by setting the Quest[] Lua table directly, it's better to use these functions because they also update the quest tracker HUD and send OnQuestStateChange messages that your scripts can listen for.

To update the quest tracker in Lua – for example, after updating a counter variable – use this Lua function:

  • UpdateTracker()

Conditional() Function

The Conditional() function checks a condition. If true, it returns a return value; otherwise it returns a blank string.

  • Conditional( condition, returnValue )

where:

  • condition is a Boolean value (Lua true/false condition)
  • returnValue is a string

Example:

  • Dialogue Text: "Introducing [lua(Conditional(Variable["WasKnighted"], "Sir ")] Ralph."

GetEntryText(), GetEntryBool(), GetEntryNumber() Functions

The functions GetEntryText(), GetEntryBool(), and GetEntryNumber() retrieve the values of dialogue entry fields from the dialogue database. Dialogue entry fields are not included in the Lua environment, but you can these functions to get their values directly from the database. They retrieve entries from the currently-active conversation (if a conversation is active).

  • GetEntryText( entryID, fieldName )
  • GetEntryBool( entryID, fieldName )
  • GetEntryNumber( entryID, fieldName )

where:

  • entryID is the ID of a dialogue entry in the currently-active conversation, and
  • fieldName is the name of a field in that dialogue entry such as "Menu Text".

GetLocalizedText() Function

The function GetLocalizedText() retrieves localized versions of fields in the Actor, Item, Quest, or Location tables. For information about setting up localized fields, see Localization.

  • GetLocalizedText( tableName, elementName, fieldName )

where:

  • tableName is "Actor", "Item", "Quest", or "Location",
  • elementName is the name of an element in the table (e.g., "Player" in the Actor table), and
  • fieldName is the name of the field.

GetLocalizedText() Example:

Say your actors have a "Nickname" field and a Spanish-localized field named "Nickname es". To use the localized version in a conversation, use the [lua(...)] tag to call GetLocalizedText():

  • Dialogue Text: You must talk to [lua( GetLocalizedText("Actor", "Boss", "Nickname") )].

GetTextTableValue() Function

The function GetTextTableValue() retrieves the localized translation of a text table field. It uses the text table assigned to the Dialogue Manager's Localization Settings section. If that text table doesn't have the specified field, it checks for a UILocalizationManager component and uses its text table.

  • GetTextTableValue( fieldName )

RandomElement() Function

The function RandomElement() returns a random element from a list. It's commonly used in [lua()] tags to add variety to your dialogue text.

  • RandomElement( string )

where string is a string of elements separated by the horizontal bar character ('|').

RandomElement() Example:

Say you have an NPC that greets the character with a random honorific title. In your dialogue database, click on the Variables tab and define a variable named Honorifics that contains this list:

"Esteemed|Revered|Great|Magnificent"

Or, to set it in Lua code:

Variable["Honorifics"] = "Esteemed|Revered|Great|Magnificent"

In the dialogue entry, set the text to:

  • Dialogue Text: Greetings, [lua(RandomElement(Variable["Honorifics"]))] One!

The result is that the NPC will randomly use one of the element in the Honorifics list, such as "Greetings, Esteemed One!" or "Greetings, Great One!"

The source string doesn't have to be set at design time. You can generate it dynamically during gameplay. You can use RandomElement() for other purposes, too, such giving the player a random item upon completion of a quest, or even choosing a random quest out of a list.

RandomizeNextEntry() Function

The function RandomizeNextEntry() tells the next NPC dialogue entry to choose randomly randomly from the list of valid NPC dialogue entries instead of using the first one in the list. It's equivalent to the RandomizeNextEntry() sequencer command, giving you the choice of whether you want to use a sequencer command or a Lua function. It takes no arguments:

  • RandomizeNextEntry()

Lua Networking Functions

The Dialogue System includes Lua functions that synchronize variables and quest states to all clients using Unity Networking's High Level API (UNET HLAPI). To make these functions available:

  1. Add this Scripting Define Symbol: USE_UNET
  2. Then add a Lua Network Commands component to your player prefab(s). It will add these functions:
  • NetSetBool( variableName, value )
  • NetSetNumber( variableName, value )
  • NetSetString( variableName, value )

The functions above set a variable locally and on all other clients. Use in place of Variable["foo"] = value when you want all clients to receive the value of the variable.

  • NetSetQuestState( questName, state )
  • NetSetQuestEntryState( questName, entryNumber, state )

The functions above set a quest state or quest entry state on all clients. Use in place of SetQuestState() and SetQuestEntryState().

How to Use Lua in Your C# Scripts

For details on the scripting distinction between database fields and Lua values, see Dialogue Database Fields and Lua Values.

DialogueLua Class

The PixelCrushers.DialogueSystem.DialogueLua class is the easiest way to access Lua data.

To get and set data in the standard Dialogue System Lua tables – Actor[], Item[], Location[] and Variable[] – use these methods:

Method Description Example
GetVariable() Get the value of a variable* bool hasBox = DialogueLua.GetVariable("hasBox").asBool
SetVariable() Set the value of a variable DialogueLua.SetVariable("hasBox", true);
GetActorField() Get the value of a field in an actor int xp = DialogueLua.GetActorField("Player", "XP").asInt;
SetActorField() Set the value of a field in an actor DialogueLua.SetActorField("Player", "Intoxicated", true);
GetItemField() Get the value of a field in an item float weight = DialogueLua.GetItemField("Anvil", "Weight").asFloat;
SetItemField() Set the value of a field in an item DialogueLua.SetItemField("Anvil", "Cost", 50);
GetQuestField() Get the value of a field in a quest. Equivalent to GetItemField() string state = DialogueLua.GetQuestField("Kill 5 Rats", "State").asString;
SetQuestField() Set the value of a field in a quest. Equivalent to SetItemField() DialogueLua.SetQuestField("Kill 5 Rats", "State", "success");
GetLocationField() Get the value of a field in a location string desc = DialogueLua.GetLocationField("Moonbase", "Description").asString;
SetLocationField() Set the value of a field in a location DialogueLua.SetLocationField("Moonbase", "Description", "A desolate lunar spaceport.");

The DialogueLua class automatically converts table indices' spaces and hyphens to underscores. When using the DialogueLua class, you can ignore the note in Important Note About Table Indices. (However, when bypassing the DialogueLua class and using the Lua class directly, you must remember to convert spaces and hyphens to underscores yourself. You can use the DialogueLua.StringToTableIndex() function to do this.)

The DialogueLua.GetXXX() methods return a Lua.Result value. To get a basic data type, use properties such as asString, asInt, asFloat, and asBool. For example:

int age = DialogueLua.GetActorField("Player", "Age").asInt;

The Actor[], Item[], and Location[] tables are two-dimensional, meaning each element in the table has fields. Use the DialogueLua.GetXXXField() methods to access their fields.

The Variable[] table, on the other hand, is one-dimensional. The elements are regular data types (Boolean, string, number, etc.), so you cannot use the DialogueLua.GetXXXField() methods. Instead, use DialogueLua.GetVariable().

bool gotMilk = DialogueLua.GetVariable("Got Milk").asBool;

Note: DialogueLua.GetVariable() has overloaded methods in which you can specify a default value if the variable isn't defined. Using these overloaded methods, you don't need to use .asXXX at the end. Examples:

bool gotMilk = DialogueLua.GetVariable("Got Milk", false);
string nickname = DialogueLua.GetVariable("Nickname", "The Kid");

QuestLog Class

The PixelCrushers.DialogueSystem.QuestLog class provides simpler functions to work with quests. (See Quests.)

Localization

To get the version of a field for the current language, use the localized versions of these methods:

Method Description
GetLocalizedActorField() Get the value of a localized field in an actor (e.g., "Description es" for Spanish)
SetLocalizedActorField() Set the value of a localized field in an actor
GetLocalizedItemField() Get the value of a localized field in an item
SetLocalizedItemField() Set the value of a localized field in an item
GetLocalizedQuestField() Get the value of a localized field in a quest. Equivalent to GetLocalizedItemField()
SetLocalizedQuestField() Set the value of a localized field in a quest. Equivalent to SetLocalizedItemField()
GetLocalizedLocationField() Get the value of a localized field in a location
SetLocalizedLocationField() Set the value of a localized field in a location

For example:

string localizedQuestName = DialogueLua.GetLocalizedQuestField("Kill 5 Rats", "Name").asString;

Lua Class

The PixelCrushers.DialogueSystem.Lua class provides lower-level access to the Lua environment through these functions:

Method Description Example
Run() Run Lua code and return a Lua.Result structure int nextYear = Lua.Run("return Actor['Player'].Age + 1").AsInt;
IsTrue() Run Lua code and return true if the Lua result is true, otherwise false if (Lua.IsTrue("Actor['Player'].Age >= 21")) {...}
RegisterFunction() Register a C# method as a Lua function Lua.RegisterFunction("Exists", null, typeof(MyClass).GetMethod("Exists")); (*see below)

Return Values

Remember that Lua.Run() returns a Lua.Result that can be a Boolean, string, number, or table. To get the Boolean value, you need to add ".AsBool", as in this example:

if (Lua.Run("return Variable['Kissed_the_Frog']").asBool) {
//(Player kissed the frog, so do something.)
}

Similarly, if your variable is a number, you can do this:

int myCoins = Lua.Run("return Variable['numberOfCoins']").AsInt);

Since Lua.IsTrue() always returns a Boolean value (true or false), you don't need to add asXXX to the end:

if (Lua.IsTrue("Variable['Kissed_the_Frog']")) {
//(Player kissed the frog, so do something.)
}

Registering Functions

(Video Tutorial: How to Connect Your Own Code to Lua)

The RegisterFunction() method lets you tie your own C# code into the Lua environment. This is extremely handy to add new capabilities to your dialogue entry Conditions and Scripts. Use the corresponding UnregisterFunction() method to unregister the C# method from Lua.

You can also add these functions to the "..." Lua dropdown wizards. See: Custom Lua Function Info For Dropdown Wizards.

For example, say you want a dialogue entry to be available only when a certain GameObject named "White Elephant" is in the scene. You want to be able to set the dialogue entry's Conditions field to this:

  • Conditions: GameObjectExists("White Elephant")

Simply add this class to your scene:

using UnityEngine;
using PixelCrushers.DialogueSystem;
public class MyLuaFunctions : MonoBehaviour
{
void OnEnable()
{
Lua.RegisterFunction(nameof(GameObjectExists), this, SymbolExtensions.GetMethodInfo(() => GameObjectExists(string.Empty)));
}
void OnDisable()
{
// Note: If this script is on your Dialogue Manager & the Dialogue Manager is configured
// as Don't Destroy On Load (on by default), don't unregister Lua functions.
Lua.UnregisterFunction(nameof(GameObjectExists)); // <-- Only if not on Dialogue Manager.
}
public bool GameObjectExists(string name)
{
return GameObject.Find(name) != null;
}
}
A static class that provides a global Lua virtual machine.
Definition Lua.cs:18
static void UnregisterFunction(string functionName)
Unregisters a C# function.
Definition Lua.cs:319
static void RegisterFunction(string functionName, object target, MethodInfo method)
Registers a C# function with the Lua interpreter so it can be used in Lua.
Definition Lua.cs:302
Definition SymbolExtensions.cs:13
static MethodInfo GetMethodInfo(Expression< Action > expression)
Given a lambda expression that calls a method, returns the method info.
Definition SymbolExtensions.cs:20

Note that we passed an empty string to GameObjectExists in the OnEnable method. This is how we specify what parameters the Lua function expects. The valid parameter types are listed in Data Types Allowed in Lua Functions.

If you're writing your own Lua functions, the best way to start is to use the Starter Template Script for Custom Lua Functions.

Data Types Allowed in Lua Functions

IMPORTANT: C# methods registered with Lua must use double for numbers, not float or int.

Only use these types in your Lua functions' parameters and return values:

Type Notes
double LuaInterpreter uses doubles for all number types; you can cast to (int), (float), etc inside your function if necessary
bool Use as normal
string Use as normal

Important Notes:

  • Lua treats all numbers as double. In your C# methods, use double instead of float or int.
  • Don't try to register more than one C# method with the same function name. For example, if you write a MonoBehaviour that registers a function, don't add that MonoBehaviour to multiple characters in the scene since each character will try to register the same function. In this case, you may want to add only one instance of the MonoBehaviour to the Dialogue Manager GameObject instead.

Starter Template Script for Custom Lua Functions

You can find a starter template script in Templates ► TemplateCustomLua.cs. To add your own Lua functions, make a copy of this template and customize it as indicated by the comments in the script.

Custom Lua Function Info For Dropdown Wizards

To make your custom Lua functions accessible in the "..." dropdown wizards (such as Conditions and Script fields), create a Custom Lua Function Info asset. Right-click in the Project view and select Create → Pixel Crushers → Dialogue System → Custom Lua Function Info.

If you want a function to appear in the Conditions wizard, add it to the Condition Functions section. If you want it to appear in the Script wizard, add it to the Script Functions section.

For each function, specify the function name and the number and types of parameters. For Condition Functions, also specify the return value type.

Lua Observers

Monitor Variable Value Changes

In some cases, you may want to be notified when the value of a Lua variable changes.

To monitor a Lua variable:

  1. Add its name to Language.Lua.Assignment.MonitoredVariables.
  2. Then register a method with the C# event Language.Lua.Assignment.VariableChanged.

For example, to monitor a variable named "gold":

Language.Lua.Assignment.VariableChanged += OnVariableChanged;
...
void OnVariableChanged(string variableName, object variableValue)
{
Debug.Log($"{variableName} value changed to: {variableValue}");
}
Definition Assignment.cs:7
static System.Action< string, object > VariableChanged
Definition Assignment.cs:15
static HashSet< string > MonitoredVariables
Definition Assignment.cs:14
Definition Assignment.cs:5
Definition Assignment.cs:5

Tip: If you want to monitor all variables in your dialogue database (which is probably overkill in most situations):

List< Variable > variables
The variables in the database.
Definition DialogueDatabase.cs:73
A static class that adds additional Chat Mapper-related functionality to the Lua environment,...
Definition DialogueLua.cs:21
static string StringToTableIndex(string s)
Returns the version of a string usable as the index to a Chat Mapper table.
Definition DialogueLua.cs:887
A static class that provides a simplified interface to the Dialogue System's core functions.
Definition DialogueManager.cs:14
static DialogueDatabase masterDatabase
Gets the master database.
Definition DialogueManager.cs:63

Using Language.Lua.Assignment.MonitoredVariables is very efficient. It has virtually no performance impact and will raise the C# event as soon as the variable changes.

Monitor General Lua Expressions

If you want to monitor other Lua info, the DialogueManager class lets you manage observers on Lua expressions using these methods:

Method Description Example
DialogueManager.AddLuaObserver() Add an observer on a Lua expression DialogueManager.AddLuaObserver("Variable['Credits']", LuaWatchFrequency.EveryDialogueEntry, OnCreditsChanged);
DialogueManager.RemoveLuaObserver() Remove an observer DialogueManager.RemoveLuaObserver("Variable['Credits']");
DialogueManager.RemoveAllObservers() Remove all observers DialogueManager.RemoveAllObservers();

AddLuaObserver() adds an observer on a Lua expression that will be checked on a specified frequency. The frequency can be EveryUpdate, EveryDialogueEntry, or EndOfConversation. If the expression changes, the Dialogue System will invoke a delegate that takes the form:

void MyDelegate(LuaWatchItem luaWatchItem, Lua.Result newValue) {...}
Watch item for Lua observers.
Definition LuaWatchItem.cs:17
Stores a Lua interpreter result (LuaValue) and provides easy conversion to basic types.
Definition Lua.cs:24

Example:

DialogueManager.AddLuaObserver("Variable['Credits']", LuaWatchFrequency.EveryDialogueEntry, OnCreditsChanged);
void OnCreditsChanged(LuaWatchItem luaWatchItem, Lua.Result newValue) {
Debug.Log("Number of credits changed to: " + newValue.AsInt);
}
static void AddLuaObserver(string luaExpression, LuaWatchFrequency frequency, LuaChangedDelegate luaChangedHandler)
Adds a Lua expression observer.
Definition DialogueManager.cs:1018
LuaWatchFrequency
Lua watch frequencies.
Definition LuaWatchers.cs:12

Note: For best performance, limit the number of observers you set, especially when the frequency is EveryUpdate. Each observer requires an extra Lua call to evaluate the current state of the Lua expression.

RemoveLuaObserver() removes an observer. The observer is identified by the Lua expression, which should exactly match the same string that you passed to AddLuaObserver(). RemoveAllLuaObservers() removes all observers.

Lua Console

The Lua Console component adds an in-game console in which you can run Lua expressions. By default, the console is mapped to ~+L but you can change the key binding.

Lua Under the Hood

LuaInterpreter

The Dialogue System uses a customized, public domain fork of LuaInterpreter that does not implement the following functions:

  • basic library: collectgarbage(), load(), rawequal(), rawlen(), rawset(), xpcall()
  • coroutines library: all functions
  • modules library: all functions
  • string library: dump(), format(), gmatch, gsub, match
  • table library: pack(), unpack()
  • bit32 library: all functions
  • input library: functions defined but disabled (to prevent malicious code insertion)
  • os: functions defined but disabled (to prevent malicious code insertion)
  • debug: all functions

Using Other Lua Implementations

The Dialogue System provides a PixelCrushers.DialogueSystem.Lua wrapper class which isolates the actual Lua implementation from the rest of the Dialogue System. If you want to use a different Lua implementation, you only need to replace these classes:

  • Lua.cs: The main wrapper class.
  • LuaTableWrapper.cs: A wrapper that allows you to handle Lua tables similarly to C# dictionaries.
  • DialogueLua.cs: Contains some Lua Interpreter-specific optimizations.

Alternative support is built-in for NLua. (See below.)

NLua Alternative

The Dialogue System also supports using NLua. To use NLua:

  1. Download the Lua 5.4 binaries: http://luabinaries.sourceforge.net/download.html
    • Put them in Plugins/x86_64/, etc.
  2. Download KeraLua: https://github.com/NLua/KeraLua
    • Add the 'src' folder to your project, somewhere in the Plugins folder, such as Assets/Plugins/KeraLua/src
    • Delete the Properties subfolder.
  3. Download NLua: https://github.com/NLua/NLua
    • Add the 'src' folder to your project, somewhere in the Plugins folder, such as Assets/Plugins/NLua/src
    • Delete the Properties subfolder.
  4. Select menu item Edit > Project Settings. In the Player section, add these symbols to Scripting Define Symbols:
NETSTANDARD;USE_NLUA

<< Welcome to the Dialogue System for Unity! | Cutscene Sequences >>